Skip to main content

Downloading files

A download action enables the user to download a file to hard disk upon clicking a button. In order to do so, the following steps need to be taken:

  1. Add a DownloadButton in the parametrization class of the corresponding entity type:

    import viktor as vkt


    class Parametrization(vkt.Parametrization):
    download = vkt.DownloadButton('Download', method='download_file')
  2. Add the download method (in this case download_file) on the corresponding controller class of the entity type to link the DownloadButton, and return the file (content) as DownloadResult:

    import viktor as vkt


    class Controller(vkt.Controller):

    def download_file(self, params, **kwargs):
    return vkt.DownloadResult('file content', 'filename.txt')

Downloading a File object

DownloadResult directly accepts a File object as input. This type is often returned by VIKTOR functions such as utils' document conversions and external analyses. This allows for easy handling of result files:

import viktor as vkt


class Controller(vkt.Controller):

def download_spreadsheet(self, params, **kwargs):
...
filled_spreadsheet = vkt.spreadsheet.render_spreadsheet(...)
return vkt.DownloadResult(filled_spreadsheet, 'filled_spreadsheet.xlsx')

def download_word_file(self, params, **kwargs):
...
word_file = vkt.word.render_word_file(...)
return vkt.DownloadResult(word_file, 'word_file.docx')

def download_scia_result(self, params, **kwargs):
...
result_file = scia_analysis.get_xml_output_file(as_file=True)
return vkt.DownloadResult(result_file, 'scia_result.xml')

Downloading other file types

It is also possible to download any other type of document (e.g. .txt, .xml, .json, etc.). In these cases, the DownloadResult should be passed the file content as type str or bytes. Since VIKTOR does not offer specific template for these file types, you will have to write the logic that generates the desired file content yourself.

Downloading multiple files

Downloading multiple files in one go is easy when using the zipped_files argument in a DownloadResult. The files will be bundled in a zip-file with given file_name:

DownloadResult(zipped_files={'my_file_1.txt': my_file_1, 'my_file_2.txt': my_file_2}, file_name="my_file.zip")

Alternatively, you can use the zipfile module from Python's standard library to create your own zip-file manually:

import viktor as vkt
import zipfile


class Controller(vkt.Controller):

def download_zip(self, params, **kwargs):
...

file = vkt.File()
with zipfile.ZipFile(file.source, 'w', zipfile.ZIP_DEFLATED) as z:
z.writestr('my_file_1.txt', my_file_1_content)
z.writestr('my_file_2.txt', my_file_2_content)

return vkt.DownloadResult(file, file_name="my_file.zip")