I'm currently writing a plugin that calculates values based on a QgsVectorLayer's attributes. To display and print the values I'm using a QgsComposerTextTableV2. I have several problems with my approach:

  • QGIS crashes when I try to run my plugin (virtual function call or instant minidump - I think it has to do with QgsComposerView)
  • I need to display/print 60+ pages, but after 10+ QGIS nearly stops responding
  • if QGIS doesn't crash and I try to create a PDF, it takes more than an hour for ~60 pages
  • I couldn't find a way to increase the height of the table headers
  • the value of one cell can consist of multiple lines, that's why I'm leaving the frame calculation up to QGIS

Is using QgsComposerTextTableV2 a good idea or are there better options to display/print large tables in QGIS/python?

edit: ReportLab seems to be a good option, testing it now.

QGIS version 2.14.3

Below is a simplified version of my code, which can be executed in the QGIS python console

from qgis.core import QgsComposition, QgsComposerTextTableV2, QgsComposerFrame, QgsComposerTableColumn
from qgis.gui import QgsComposerView
import qgis.utils

windowTitle = 'myComposer'
iface.createNewComposer(windowTitle)  # returns virtual that can't be used

# composition
mapSettings = iface.mapCanvas().mapSettings()
composition = QgsComposition(mapSettings)
paperHeight = 297
paperWidth = 420  # 420 results in 422 somehow using QPrinter, QPainter directly with QComposition
composition.setPaperSize(paperWidth, paperHeight)

# table
textTable = QgsComposerTextTableV2(composition, False)
textTable.setHeaderMode(1)  # show header on all pages
textTable.setResizeMode(3)  # RepeatUntilFinished

# frame
x = 20
y = 10
frameHeight = paperHeight - 2*y
frameWidth = paperWidth - x - y
tableFrame = QgsComposerFrame(composition, textTable, x, y, frameWidth, frameHeight)

# columns
columns = []
x = 10
i = 0
while i < x:
    tempColumn = QgsComposerTableColumn()
    tempColumn.setHeading('heading that doesn\'t fit\n into a single line')
    i += 1

# content
contentList = []
x = 10
y = 500
i = 0
j = 0
while i < y:
    newRow = []
    while j < x:
        newRow.append('row ' +  str(i) + ' column ' + str(j))
        j += 1
    j = 0
    i += 1

# get composerView
activeComposers = iface.activeComposers()
for composer in activeComposers:
    if composer.composerWindow().windowTitle() == windowTitle:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.