Display a report
PDF files can directly be presented in a view using the PDFView.
PDF view
Implementation
There are 3 ways to create a PDF view:
From a File-object
The easiest way to show a PDF document in the PDFView is by using a File object:
import viktor as vkt
class Controller(vkt.Controller):
@vkt.PDFView("PDF Viewer")
def get_pdf_view(self, params, **kwargs):
...
return vkt.PDFResult(file=my_pdf_file)
If File.from_url is used, the file will always be downloaded first and not rendered from the website, as in the case
with the direct URL.
From a URL
If a PDF is located on the internet one can also use the URL directly. This does not download the file locally, but renders it directly from the hosting website:
import viktor as vkt
class Controller(vkt.Controller):
@vkt.PDFView("PDF Viewer")
def get_pdf_view(self, params, **kwargs):
return vkt.PDFResult(url="https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf")
Some websites don't allow files to be shared this way. This will result in the PDF not showing up in the view. If that
is the case, the PDFView can be created from a 'file from url', which will download the file locally first and
display it subsequently:
import viktor as vkt
class Controller(vkt.Controller):
@vkt.PDFView("PDF Viewer")
def get_pdf_view(self, params, **kwargs):
file = vkt.File.from_url(url="https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf")
return vkt.PDFResult(file=file)
From a path
Finally, it is possible to create a PDFView directly from a path (for convenience, to skip creating a File from
path first):
from pathlib import Path
import viktor as vkt
class Controller(vkt.Controller):
@vkt.PDFView("PDF Viewer")
def get_pdf_view(self, params, **kwargs):
file_path = Path(__file__).parent / 'sample.pdf'
return vkt.PDFResult.from_path(file_path)
Testing
mock_View decorator for easier testing of view methods
Methods decorated with @PDFView need to be
mocked within the context of (automated) testing.
import unittest
from viktor.testing import mock_View
from app.my_entity_type.controller import MyEntityTypeController
class TestMyEntityTypeController(unittest.TestCase):
@mock_View(MyEntityTypeController)
def test_pdf_view(self):
params = ...
result = MyEntityTypeController().pdf_view(params=params)
self.assertEqual(result.file.getvalue_binary(), ...)