Skip to content

Instantly share code, notes, and snippets.

@pylixm
Created March 3, 2021 10:30
Show Gist options
  • Select an option

  • Save pylixm/5e4d3ab547c1ef8f0118e969237950c4 to your computer and use it in GitHub Desktop.

Select an option

Save pylixm/5e4d3ab547c1ef8f0118e969237950c4 to your computer and use it in GitHub Desktop.
pdf_pyqt5.py
# read docs : https://www.learnpyqt.com/examples/python-pdf-report-generator/
from PyQt5.QtWidgets import QPushButton, QLineEdit, QApplication, QFormLayout, QWidget, QTextEdit, QMessageBox, QSpinBox
from PyQt5.QtCore import QObject, QRunnable, QThreadPool, pyqtSignal, pyqtSlot
from reportlab.pdfgen.canvas import Canvas
import os
import textwrap
from datetime import datetime
from pdfrw import PdfReader
from pdfrw.buildxobj import pagexobj
from pdfrw.toreportlab import makerl
class WorkerSignals(QObject):
"""
Defines the signals available from a running worker thread.
"""
error = pyqtSignal(str)
file_saved_as = pyqtSignal(str)
class Generator(QRunnable):
"""
Worker thread
Inherits from QRunnable to handle worker thread setup, signals
and wrap-up.
:param data: The data to add to the PDF for generating.
"""
def __init__(self, data):
super().__init__()
self.data = data
self.signals = WorkerSignals()
@pyqtSlot()
def run(self):
try:
outfile = "result.pdf"
template = PdfReader("template.pdf", decompress=False).pages[0]
template_obj = pagexobj(template)
canvas = Canvas(outfile)
xobj_name = makerl(canvas, template_obj)
canvas.doForm(xobj_name)
ystart = 443
# Prepared by
canvas.drawString(170, ystart, self.data['name'])
# Date: Todays date
today = datetime.today()
canvas.drawString(410, ystart, today.strftime('%F'))
# Device/Program Type
canvas.drawString(230, ystart-28, self.data['program_type'])
# Product code
canvas.drawString(175, ystart-(2*28), self.data['product_code'])
# Customer
canvas.drawString(315, ystart-(2*28), self.data['customer'])
# Vendor
canvas.drawString(145, ystart-(3*28), self.data['vendor'])
ystart = 250
# Program Language
canvas.drawString(210, ystart, "Python")
canvas.drawString(430, ystart, self.data['n_errors'])
comments = self.data['comments'].replace('\n', ' ')
if comments:
lines = textwrap.wrap(comments, width=65) # 45
first_line = lines[0]
remainder = ' '.join(lines[1:])
lines = textwrap.wrap(remainder, 75) # 55
lines = lines[:4] # max lines, not including the first.
canvas.drawString(155, 223, first_line)
for n, l in enumerate(lines, 1):
canvas.drawString(80, 223 - (n*28), l)
canvas.save()
except Exception as e:
self.signals.error.emit(str(e))
return
self.signals.file_saved_as.emit(outfile)
class Window(QWidget):
def __init__(self):
super().__init__()
self.threadpool = QThreadPool()
self.name = QLineEdit()
self.program_type = QLineEdit()
self.product_code = QLineEdit()
self.customer = QLineEdit()
self.vendor = QLineEdit()
self.n_errors = QSpinBox()
self.n_errors.setRange(0, 1000)
self.comments = QTextEdit()
self.generate_btn = QPushButton("Generate PDF")
self.generate_btn.pressed.connect(self.generate)
layout = QFormLayout()
layout.addRow("Name", self.name)
layout.addRow("Program Type", self.program_type)
layout.addRow("Product Code", self.product_code)
layout.addRow("Customer", self.customer)
layout.addRow("Vendor", self.vendor)
layout.addRow("No. of Errors", self.n_errors)
layout.addRow("Comments", self.comments)
layout.addRow(self.generate_btn)
self.setLayout(layout)
def generate(self):
self.generate_btn.setDisabled(True)
data = {
'name': self.name.text(),
'program_type': self.program_type.text(),
'product_code': self.product_code.text(),
'customer': self.customer.text(),
'vendor': self.vendor.text(),
'n_errors': str(self.n_errors.value()),
'comments': self.comments.toPlainText()
}
g = Generator(data)
g.signals.file_saved_as.connect(self.generated)
g.signals.error.connect(print) # Print errors to console.
self.threadpool.start(g)
def generated(self, outfile):
self.generate_btn.setDisabled(False)
try:
os.startfile(outfile)
except Exception:
# If startfile not available, show dialog.
QMessageBox.information(self, "Finished", "PDF has been generated")
app = QApplication([])
w = Window()
w.show()
app.exec_()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment