Skip to main content

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:

  1. From a File-object
  2. From a URL
  3. From a path

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)
note

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

New in v13.3.0

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(), ...)