• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

python3+PyQt5实现文档打印功能

python 搞代码 4年前 (2022-01-09) 30次浏览 已收录 0个评论

这篇文章主要为大家详细介绍了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&Cursor") htmlButton = QPushButton("Print via &HTML") painterButton = QPushButton("Print via Q&Painter") quitButton = QPushButton("&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()<strong style="color:transparent">本文来源gao@daima#com搞(%代@#码@网&</strong>)))  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 align=right><img src=':/logo.png'></p>"   "<p align=right>Greasy Hands Ltd."   "<br>New Lombard Street"   "<br>London<br>WC13 4PX<br>{0}</p>"   "<p>{1}</p><p>Dear {2},</p>"   "<p>The balance of your account is $ {3:,.2f}.").format(   date, address, contact, float(balance))  if balance < 0:  htmltext += (" <p><font color=red><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>"   "<table border=1 cellpadding=2 "   "cellspacing=2><tr><td colspan=3>"   "Transactions</td></tr>")  for date, amount in statement.transactions:  color, status = "black", "Credit"  if amount < 0:   color, status = "red", "Debit"  htmltext += ("<tr><td align=right>{0}</td>"    "<td>{1}</td><td align=right>"    "<font color={2}>$ {3:,.2f}</font></td></tr>".format(    date.toString(DATE_FORMAT), status, color,float(abs(amount))))  htmltext += ("</table></p><p style='page-break-after:always;'>"   "We hope to continue doing "   "business with you,<br>Yours sincerely,"   "<br><br>K. Longrey, Manager</p>") 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:  cursor.insertBlock(bodyFormat, redBodyCharFormat)  cursor.insertText("Please remit the amount owing "     "immediately.")  else:  cursor.insertBlock(bodyFormat, bodyCharFormat)  cursor.insertText("We are delighted to have done "     "business with you.")  cursor.insertBlock(bodyFormat, bodyCharFormat)  cursor.insertText("Transactions:")  table = cursor.insertTable(len(statement.transactions), 3,     tableFormat)  row = 0  for date, amount in statement.transactions:  cellCursor = table.cellAt(row, 0).firstCursorPosition()  cellCursor.setBlockFormat(rightBodyFormat)  cellCursor.insertText(date.toString(DATE_FORMAT),     bodyCharFormat)  cellCursor = table.cellAt(row, 1).firstCursorPosition()  if amount > 0:   cellCursor.insertText("Credit", bodyCharFormat)  else:   cellCursor.insertText("Debit", bodyCharFormat)  cellCursor = table.cellAt(row, 2).firstCursorPosition()  cellCursor.setBlockFormat(rightBodyFormat)  format = bodyCharFormat  if amount < 0:   format = redBodyCharFormat  cellCursor.insertText("$ {0:,.2f}".format(float(amount)), format)  row += 1  cursor.setPosition(mainFrame.lastPosition())  cursor.insertBlock(bodyFormat, bodyCharFormat)  cursor.insertText("We hope to continue doing business "    "with you,")  cursor.insertBlock(bodyFormat, bodyCharFormat)  cursor.insertText("Yours sincerely")  cursor.insertBlock(bodyFormat)  if page == len(self.statements):  cursor.insertBlock(bodyFormat, bodyCharFormat)  else:  cursor.insertBlock(lastParaBodyFormat, bodyCharFormat)  cursor.insertText("K. Longrey, Manager")  page += 1 document.print_(self.printer) def printViaQPainter(self): dialog = QPrintDialog(self.printer, self) if not dialog.exec_():  return LeftMargin = 72 sansFont = QFont("Helvetica", 10) sansLineHeight = QFontMetrics(sansFont).height() serifFont = QFont("Times", 11) fm = QFontMetrics(serifFont) DateWidth = fm.width(" September 99, 2999 ") CreditWidth = fm.width(" Credit ") AmountWidth = fm.width(" W999999.99 ") serifLineHeight = fm.height() logo = QPixmap(":/logo.png") painter = QPainter(self.printer) pageRect = self.printer.pageRect() page = 1 for statement in self.statements:  painter.save()  y = 0  x = pageRect.width() - logo.width() - LeftMargin  painter.drawPixmap(x, 0, logo)  y += logo.height() + sansLineHeight  painter.setFont(sansFont)  painter.drawText(x, y, "Greasy Hands Ltd.")  y += sansLineHeight  painter.drawText(x, y, "New Lombard Street")  y += sansLineHeight  painter.drawText(x, y, "London")  y += sansLineHeight  painter.drawText(x, y, "WC13 4PX")  y += sansLineHeight  painter.drawText(x, y,   QDate.currentDate().toString(DATE_FORMAT))  y += sansLineHeight  painter.setFont(serifFont)  x = LeftMargin  for line in statement.address.split(", "):  painter.drawText(x, y, line)  y += serifLineHeight  y += serifLineHeight  painter.drawText(x, y, "Dear {0},".format(statement.contact))  y += serifLineHeight  balance = statement.balance()  painter.drawText(x, y, "The balance of your account is $ {0:,.2f}".format(float(balance)))  y += serifLineHeight  if balance < 0:  painter.setPen(Qt.red)  text = "Please remit the amount owing immediately."  else:  text = ("We are delighted to have done business "   "with you.")  painter.drawText(x, y, text)  painter.setPen(Qt.black)  y += int(serifLineHeight * 1.5)  painter.drawText(x, y, "Transactions:")  y += serifLineHeight  option = QTextOption(Qt.AlignRight|Qt.AlignVCenter)  for date, amount in statement.transactions:  x = LeftMargin  h = int(fm.height() * 1.3)  painter.drawRect(x, y, DateWidth, h)  painter.drawText(   QRectF(x + 3, y + 3, DateWidth - 6, h - 6),   date.toString(DATE_FORMAT), option)  x += DateWidth  painter.drawRect(x, y, CreditWidth, h)  text = "Credit"  if amount < 0:   text = "Debit"  painter.drawText(   QRectF(x + 3, y + 3, CreditWidth - 6, h - 6),   text, option)  x += CreditWidth  painter.drawRect(x, y, AmountWidth, h)  if amount < 0:   painter.setPen(Qt.red)  painter.drawText(   QRectF(x + 3, y + 3, AmountWidth - 6, h - 6),   "$ {0:,.2f}".format(float(amount)),   option)  painter.setPen(Qt.black)  y += h  y += serifLineHeight  x = LeftMargin  painter.drawText(x, y, "We hope to continue doing "     "business with you,")  y += serifLineHeight  painter.drawText(x, y, "Yours sincerely")  y += serifLineHeight * 3  painter.drawText(x, y, "K. Longrey, Manager")  x = LeftMargin  y = pageRect.height() - 72  painter.drawLine(x, y, pageRect.width() - LeftMargin, y)  y += 2  font = QFont("Helvetica", 9)  font.setItalic(True)  painter.setFont(font)  option = QTextOption(Qt.AlignCenter)  option.setWrapMode(QTextOption.WordWrap)  painter.drawText(   QRectF(x, y, pageRect.width() - 2 * LeftMargin, 31),   "The contents of this letter are for information "   "only and do not form part of any contract.",   option)  page += 1  if page <= len(self.statements):  self.printer.newPage()  painter.restore()if __name__ == "__main__": app = QApplication(sys.argv) form = Form() form.show() app.exec_()

运行结果:

相关推荐:

python3+PyQt5实现支持多线程的页面索引器应用程序

python3+PyQt5泛型委托详解

以上就是python3+PyQt5实现文档打印功能的详细内容,更多请关注搞代码gaodaima其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:python3+PyQt5实现文档打印功能

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址