Skip to content

Instantly share code, notes, and snippets.

@chris-marsh
Created October 13, 2017 14:55
Show Gist options
  • Save chris-marsh/351febf755c05a4e57cf4dc2b625aab1 to your computer and use it in GitHub Desktop.
Save chris-marsh/351febf755c05a4e57cf4dc2b625aab1 to your computer and use it in GitHub Desktop.
PyQt5 - Print paginated QTableWidget
from PyQt5 import QtWidgets, QtCore, QtPrintSupport, QtGui
class Window(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.setWindowTitle(self.tr('Document Printer'))
self.table = QtWidgets.QTableWidget(200, 5, self)
for row in range(self.table.rowCount()):
for col in range(self.table.columnCount()):
item = QtWidgets.QTableWidgetItem('(%d, %d)' % (row, col))
item.setTextAlignment(QtCore.Qt.AlignCenter)
self.table.setItem(row, col, item)
self.table.setHorizontalHeaderLabels(
'SKU #|NAME|DESCRIPTION|QUANTITY|PRICE'.split('|'))
self.buttonPrint = QtWidgets.QPushButton('Print', self)
self.buttonPrint.clicked.connect(self.handlePrint)
self.buttonPreview = QtWidgets.QPushButton('Preview', self)
self.buttonPreview.clicked.connect(self.handlePreview)
layout = QtWidgets.QGridLayout(self)
layout.addWidget(self.table, 0, 0, 1, 2)
layout.addWidget(self.buttonPrint, 1, 0)
layout.addWidget(self.buttonPreview, 1, 1)
def handlePrint(self):
dialog = QtPrintSupport.QPrintDialog()
if dialog.exec_() == QtWidgets.QDialog.Accepted:
self.handlePaintRequest(dialog.printer())
def handlePreview(self):
dialog = QtPrintSupport.QPrintPreviewDialog()
dialog.paintRequested.connect(self.handlePaintRequest)
dialog.exec_()
def handlePaintRequest(self, printer):
document = QtGui.QTextDocument()
cursor = QtGui.QTextCursor(document)
table = cursor.insertTable(
self.table.rowCount(), self.table.columnCount())
for row in range(table.rows()):
for col in range(table.columns()):
cursor.insertText(self.table.item(row, col).text())
cursor.movePosition(QtGui.QTextCursor.NextCell)
document.print_(printer)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.resize(640, 480)
window.show()
sys.exit(app.exec_())
@axsllj
Copy link

axsllj commented Jun 1, 2022

This is great, but how to print Horizontal Header Labels ?

@Axel-Erfurt
Copy link

change handlePaintRequest

    def handlePaintRequest(self, printer):
        document = QtGui.QTextDocument()
        cursor = QtGui.QTextCursor(document)
        table = cursor.insertTable(
            self.table.rowCount(), self.table.columnCount())
        for col in range(table.columns()):
            cursor.insertText(self.table.horizontalHeaderItem(col).text())
            cursor.movePosition(QtGui.QTextCursor.NextCell)
            
        for row in range(table.rows()):
            for col in range(table.columns()):
                cursor.insertText(self.table.item(row, col).text())
                cursor.movePosition(QtGui.QTextCursor.NextCell)
        document.print_(printer)

@axsllj
Copy link

axsllj commented Jun 2, 2022

Thanks, but it doesn't seem to work for me so I managed with this code:

def handlePaintRequest(self, printer):
        document = QtGui.QTextDocument()
        cursor = QtGui.QTextCursor(document)
        rows = self.tableData.rowCount()
        columns = self.tableData.columnCount()
        tableData = cursor.insertTable(rows + 1, columns)
        format = tableData.format()
        format.setHeaderRowCount(1)
        tableData.setFormat(format)
        format = cursor.blockCharFormat()
        for column in range(columns):
            cursor.setCharFormat(format)
            cursor.insertText(
                self.tableData.horizontalHeaderItem(column).text())
            cursor.movePosition(QtGui.QTextCursor.NextCell)
        for row in range(rows):
            for column in range(columns):
                cursor.insertText(
                    self.tableData.item(row, column).text())
                cursor.movePosition(QtGui.QTextCursor.NextCell)
        document.print_(printer)

Now, I can't solve to style the borders :(

@Axel-Erfurt
Copy link

You did not set style, try this

    def handlePaintRequest(self, printer):
        document = QtGui.QTextDocument()
        cursor = QtGui.QTextCursor(document)
        rows = self.tableData.rowCount()
        columns = self.tableData.columnCount()
        tableData = cursor.insertTable(rows + 1, columns)
        format = tableData.format()
        ### style
        format.setBorder(1)
        format.setBorderStyle(3)
        format.setCellSpacing(0);
        format.setTopMargin(0);
        format.setCellPadding(4)
        ###
        format.setHeaderRowCount(1)
        tableData.setFormat(format)
        format = cursor.blockCharFormat()
        for column in range(columns):
            cursor.setCharFormat(format)
            cursor.insertText(
                self.tableData.horizontalHeaderItem(column).text())
            cursor.movePosition(QtGui.QTextCursor.NextCell)
        for row in range(rows):
            for column in range(columns):
                cursor.insertText(
                    self.tableData.item(row, column).text())
                cursor.movePosition(QtGui.QTextCursor.NextCell)
        document.print_(printer)

@axsllj
Copy link

axsllj commented Jun 3, 2022

It works! Thank you so much for the help and response :)

@bclme
Copy link

bclme commented Jun 8, 2022

how to add header and footer on each page?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment