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:
-
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') -
Add the download method (in this case
download_file
) on the corresponding controller class of the entity type to link theDownloadButton
, and return the file (content) asDownloadResult
: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")