Create pdf report for custom application

Hi. I’m making an application for PedicleScrewPlanning. After the screws positions and orientations has been selected it is useful to make a pdf report showing the different views for each screw for the surgeon to use in the surgery in case it’s needed.

I tried two different approaches without the desired results:
First approach:

desktopPath = os.path.join(os.path.expanduser("~"), "Desktop")
pdfPath = os.path.join(desktopPath, "reportWithoutStyle.pdf")

printer = qt.QPrinter(qt.QPrinter.PrinterResolution)
printer.setOutputFormat(qt.QPrinter.PdfFormat)
printer.setPaperSize(qt.QPrinter.A4)
marginleft = 20
marginright = 20
margintop = 20
marginbottom = 20
printer.setPageMargins(marginleft, marginright, margintop, marginbottom, qt.QPrinter.Millimeter)
printer.setOutputFileName(pdfPath)

doc = qt.QTextDocument()

_stylesheet = """
<style>
  td, th {
    text-align:center; 
  }
  table {
    border: 1px solid black;
  }
</style>
"""

_html = """
		<html>
      <head>
        <title>PediGuide surgical planning report</title>
      </head>  
      <body>
        <table>
        <tr>
          <td>Patient name:</td>
          <td></td>
        </tr>
        <tr>
          <td>Patient ID:</td>
          <td></td>
        </tr>
        </table>
      </body>
    </html>
"""

doc.setDefaultStyleSheet(_stylesheet)
doc.setHtml(_html)
doc.setPageSize(qt.QSizeF(printer.pageRect().size()))  # hide the page number
doc.print(printer)

The problem with this approach is that it ignores stylesheets so the result is not good looking (e.g. the border of the table is not shown) and I cannot set @media print styles. However this approach does set the specified margins.

Here is an example of the result:

Second approach:

desktopPath = os.path.join(os.path.expanduser("~"), "Desktop")
pdfPath2 = os.path.join(desktopPath, "reportWithoutMargins.pdf")

ww = slicer.qSlicerWebWidget()
_html = """
  <html>
    <style>
      table {
        border: 1px solid black;
      }
    </style>
    <head>
      <title>PediGuide surgical planning report</title>
    </head>  
    <body>
      <table style=border: 1px solid black>
      <tr>
        <td>Patient name:</td>
        <td></td>
      </tr>
      <tr>
        <td>Patient ID:</td>
        <td></td>
      </tr>
      </table>
    </body>
  </html>
"""
ww.setHtml(_html)
ww.printToPdf(pdfPath2)

This approach does use styles but does not have margins which makes it not printer-friendly.

Here is an example of the result:

Could someone help to improve one of these two approaches? Thank you

PS: please have in mind that the report will probably have more than 1 page so some html tricks to have margins only on the first page will not work.

HTML is a decidedly medium-independent document format, it has no notion of pages or margins. If you want to create professional-looking PDF reports then you can use PDF creator toolkits instead, such as fpdf2 or reportlab.

1 Like

How is the current situation?

The pdf needs to show data (titles and images) based on a table template