PHP前端开发

python3+PyQt5实现文档打印功能

百变鹏仔 3小时前 #Python
文章标签 文档

这篇文章主要为大家详细介绍了python3+pyqt5实现文档打印功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文通过Python3+PyQt5实现《python Qt Gui 快速编程》这本书13章文档打印功能。本文共通过三种方式:

1、使用HTML和QTextDOcument打印文档
2、使用QTextCusor和QTextDocument打印文档
3、使用QPainter打印文档

使用Qpainter打印文档比QTextDocument需要更操心和复杂的计算,但是QPainter确实能够对输出赋予完全控制。

#!/usr/bin/env python3import mathimport sysimport htmlfrom PyQt5.QtPrintSupport import QPrinter,QPrintDialogfrom PyQt5.QtCore import (QDate, QRectF, Qt)from PyQt5.QtWidgets import (QApplication,QDialog,  QHBoxLayout,QPushButton, QTableWidget, QTableWidgetItem,QVBoxLayout)from PyQt5.QtGui import (QFont,QFontMetrics,QPainter,QTextCharFormat,    QTextCursor, QTextDocument, QTextFormat,    QTextOption, QTextTableFormat,    QPixmap,QTextBlockFormat)import qrc_resourcesfrom PyQt5.QtPrintSupport import QPrinter,QPrintDialogfrom PyQt5.QtCore import (QDate, QRectF, Qt)from PyQt5.QtWidgets import (QApplication,QDialog,  QHBoxLayout,QPushButton, QTableWidget, QTableWidgetItem,QVBoxLayout)from PyQt5.QtGui import (QFont,QFontMetrics,QPainter,QTextCharFormat,    QTextCursor, QTextDocument, QTextFormat,    QTextOption, QTextTableFormat,    QPixmap,QTextBlockFormat)import qrc_resourcesDATE_FORMAT = "MMM d, yyyy"class Statement(object): def __init__(self, company, contact, address): self.company = company self.contact = contact self.address = address self.transactions = [] # List of (QDate, float) two-tuples def balance(self): return sum([amount for date, amount in self.transactions])class Form(QDialog): def __init__(self, parent=None): super(Form, self).__init__(parent) self.printer = QPrinter() self.printer.setPageSize(QPrinter.Letter) self.generateFakeStatements() self.table = QTableWidget() self.populateTable() cursorButton = QPushButton("Print via Q&amp;Cursor") htmlButton = QPushButton("Print via &amp;HTML") painterButton = QPushButton("Print via Q&amp;Painter") quitButton = QPushButton("&amp;Quit") buttonLayout = QHBoxLayout() buttonLayout.addWidget(cursorButton) buttonLayout.addWidget(htmlButton) buttonLayout.addWidget(painterButton) buttonLayout.addStretch() buttonLayout.addWidget(quitButton) layout = QVBoxLayout() layout.addWidget(self.table) layout.addLayout(buttonLayout) self.setLayout(layout) cursorButton.clicked.connect(self.printViaQCursor) htmlButton.clicked.connect(self.printViaHtml) painterButton.clicked.connect(self.printViaQPainter) quitButton.clicked.connect(self.accept) self.setWindowTitle("Printing") def generateFakeStatements(self): self.statements = [] statement = Statement("Consality", "Ms S. Royal",  "234 Rue Saint Hyacinthe, 750201, Paris") statement.transactions.append((QDate(2007, 8, 11), 2342)) statement.transactions.append((QDate(2007, 9, 10), 2342)) statement.transactions.append((QDate(2007, 10, 9), 2352)) statement.transactions.append((QDate(2007, 10, 17), -1500)) statement.transactions.append((QDate(2007, 11, 12), 2352)) statement.transactions.append((QDate(2007, 12, 10), 2352)) statement.transactions.append((QDate(2007, 12, 20), -7500)) statement.transactions.append((QDate(2007, 12, 20), 250)) statement.transactions.append((QDate(2008, 1, 10), 2362)) self.statements.append(statement) statement = Statement("Demamitur Plc", "Mr G. Brown",  "14 Tall Towers, Tower Hamlets, London, WC1 3BX") statement.transactions.append((QDate(2007, 5, 21), 871)) statement.transactions.append((QDate(2007, 6, 20), 542)) statement.transactions.append((QDate(2007, 7, 20), 1123)) statement.transactions.append((QDate(2007, 7, 20), -1928)) statement.transactions.append((QDate(2007, 8, 13), -214)) statement.transactions.append((QDate(2007, 9, 15), -3924)) statement.transactions.append((QDate(2007, 9, 15), 2712)) statement.transactions.append((QDate(2007, 9, 15), -273)) #statement.transactions.append((QDate(2007, 11, 8), -728)) #statement.transactions.append((QDate(2008, 2, 7), 228)) #statement.transactions.append((QDate(2008, 3, 13), -508)) #statement.transactions.append((QDate(2008, 3, 22), -2481)) #statement.transactions.append((QDate(2008, 4, 5), 195)) self.statements.append(statement) def populateTable(self): headers = ["Company", "Contact", "Address", "Balance"] self.table.setColumnCount(len(headers)) self.table.setHorizontalHeaderLabels(headers) self.table.setRowCount(len(self.statements)) for row, statement in enumerate(self.statements):  self.table.setItem(row, 0, QTableWidgetItem(statement.company))  self.table.setItem(row, 1, QTableWidgetItem(statement.contact))  self.table.setItem(row, 2, QTableWidgetItem(statement.address))  item = QTableWidgetItem("$ {0:,.2f}".format(float(statement.balance())))  item.setTextAlignment(Qt.AlignRight|Qt.AlignVCenter)  self.table.setItem(row, 3, item) self.table.resizeColumnsToContents() def printViaHtml(self): htmltext = "" for statement in self.statements:  date = QDate.currentDate().toString(DATE_FORMAT)  address = html.escape(statement.address).replace(   ",", "<br>")  contact = html.escape(statement.contact)  balance = statement.balance()  htmltext += ("<p><img  alt="python3+PyQt5实现文档打印功能" ></p>"   "<p>Greasy Hands Ltd."   "<br>New Lombard Street"   "<br>London<br>WC13 4PX<br>{0}</p>"   "<p>{1}</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/00968c3c2c15" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">Python免费学习笔记(深入)</a>”;</p><p>Dear {2},</p>"   "<p>The balance of your account is $ {3:,.2f}.").format(   date, address, contact, float(balance))  if balance <font><b>Please remit the "    "amount owing immediately.</b></font>")  else:  htmltext += (" We are delighted to have done business "    "with you.")  htmltext += ("</p><p> </p><p>"   "</p>
")  for date, amount in statement.transactions:  color, status = "black", "Credit"  if amount "    "".format(    date.toString(DATE_FORMAT), status, color,float(abs(amount))))  htmltext += ("
"   "Transactions
{0}{1}"    "$ {3:,.2f}

"   "We hope to continue doing "   "business with you,
Yours sincerely,"   "

K. Longrey, Manager

") dialog = QPrintDialog(self.printer, self) if dialog.exec_():  document = QTextDocument()  document.setHtml(htmltext)  document.print_(self.printer) def printViaQCursor(self): dialog = QPrintDialog(self.printer, self) if not dialog.exec_():  return logo = QPixmap(":/logo.png") headFormat = QTextBlockFormat() headFormat.setAlignment(Qt.AlignLeft) headFormat.setTextIndent(  self.printer.pageRect().width() - logo.width() - 216) bodyFormat = QTextBlockFormat() bodyFormat.setAlignment(Qt.AlignJustify) lastParaBodyFormat = QTextBlockFormat(bodyFormat) lastParaBodyFormat.setPageBreakPolicy(  QTextFormat.PageBreak_AlwaysAfter) rightBodyFormat = QTextBlockFormat() rightBodyFormat.setAlignment(Qt.AlignRight) headCharFormat = QTextCharFormat() headCharFormat.setFont(QFont("Helvetica", 10)) bodyCharFormat = QTextCharFormat() bodyCharFormat.setFont(QFont("Times", 11)) redBodyCharFormat = QTextCharFormat(bodyCharFormat) redBodyCharFormat.setForeground(Qt.red) tableFormat = QTextTableFormat() tableFormat.setBorder(1) tableFormat.setCellPadding(2) document = QTextDocument() cursor = QTextCursor(document) mainFrame = cursor.currentFrame() page = 1 for statement in self.statements:  cursor.insertBlock(headFormat, headCharFormat)  cursor.insertImage(":/logo.png")  for text in ("Greasy Hands Ltd.", "New Lombard Street",    "London", "WC13 4PX",    QDate.currentDate().toString(DATE_FORMAT)):  cursor.insertBlock(headFormat, headCharFormat)  cursor.insertText(text)  for line in statement.address.split(", "):  cursor.insertBlock(bodyFormat, bodyCharFormat)  cursor.insertText(line)  cursor.insertBlock(bodyFormat)  cursor.insertBlock(bodyFormat, bodyCharFormat)  cursor.insertText("Dear {0},".format(statement.contact))  cursor.insertBlock(bodyFormat)  cursor.insertBlock(bodyFormat, bodyCharFormat)  balance = statement.balance()  cursor.insertText("The balance of your account is $ {0:,.2f}.".format(float(balance)))  if balance  0:   cellCursor.insertText("Credit", bodyCharFormat)  else:   cellCursor.insertText("Debit", bodyCharFormat)  cellCursor = table.cellAt(row, 2).firstCursorPosition()  cellCursor.setBlockFormat(rightBodyFormat)  format = bodyCharFormat  if amount 

运行结果: