Как повторять заголовки столбцов таблицы над разрывами страниц в PDF-выходном отчете ReportLab

Я использую ReportLab для записи таблиц в PDF-документах, и я очень доволен результатами (несмотря на то, что пока не хватаю полного понимания потоков).

Однако мне не удалось выяснить, как сделать таблицу, которая охватывает разрыв страницы, повторяются заголовки столбцов.

Ниже приведен код test.pdf в C:\Temp, который имеет строку заголовка, за которой следуют 99 строк данных.

Строка заголовков выглядит великолепно на первой странице, но я бы хотел, чтобы она повторялась в верхней части второй и третьей страниц.

Я очень хочу услышать о любых подходах, которые были использованы для этого, используя SimpleDocTemplate.

from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Frame, Spacer
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.pagesizes import A3, A4, landscape, portrait
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
from reportlab.pdfgen import canvas

pdfReportPages = "C:\\Temp\\test.pdf"
doc = SimpleDocTemplate(pdfReportPages, pagesize=A4)

# container for the "Flowable" objects
elements = []
styles=getSampleStyleSheet()
styleN = styles["Normal"]

# Make heading for each column
column1Heading = Paragraph("<para align=center>COLUMN ONE HEADING</para>",styles['Normal'])
column2Heading = Paragraph("<para align=center>COLUMN TWO HEADING</para>",styles['Normal'])
row_array = [column1Heading,column2Heading]
tableHeading = [row_array]
tH = Table(tableHeading, [6 * cm, 6 * cm])            # These are the column widths for the headings on the table
tH.hAlign = 'LEFT'
tblStyle = TableStyle([('TEXTCOLOR',(0,0),(-1,-1),colors.black),
                       ('VALIGN',(0,0),(-1,-1),'TOP'),
                       ('BOX',(0,0),(-1,-1),1,colors.black),
                       ('BOX',(0,0),(0,-1),1,colors.black)])
tblStyle.add('BACKGROUND',(0,0),(-1,-1),colors.lightblue)
tH.setStyle(tblStyle)
elements.append(tH)

# Assemble rows of data for each column
for i in range(1,100):
    column1Data = Paragraph("<para align=center> " + "Row " + str(i) + " Column 1 Data" + "</font> </para>",styles['Normal'])
    column2Data = Paragraph("<para align=center> " + "Row " + str(i) + " Column 2 Data" + "</font> </para>",styles['Normal'])
    row_array = [column1Data,column2Data]
    tableRow = [row_array]
    tR=Table(tableRow, [6 * cm, 6 * cm])   
    tR.hAlign = 'LEFT'
    tR.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),colors.white),
                            ('TEXTCOLOR',(0,0),(-1,-1),colors.black),
                            ('VALIGN',(0,0),(-1,-1),'TOP'),
                            ('BOX',(0,0),(-1,-1),1,colors.black),
                            ('BOX',(0,0),(0,-1),1,colors.black)]))
    elements.append(tR)
    del tR

elements.append(Spacer(1, 0.3 * cm))

doc.build(elements)

Ответ 1

Из документации (да, я знаю, но иногда трудно найти этот материал в руководстве):

Аргумент repeatRows указывает количество ведущих строк, которые следует повторять, когда в таблице предлагается разбивать себя.

Итак, когда вы создаете таблицу, это один из аргументов, которые вы можете передать, и он превратит первые n строк в строки заголовков, которые повторяются. Вы найдете эту часть текста на стр. 77, но раздел, относящийся к созданию таблицы, начинается на стр. 76.

http://www.reportlab.com/docs/reportlab-userguide.pdf

Ответ 2

Это код, который я разработал после того, как после рекомендации Гордона пересмотреть использование repeatRows, и он работает!

from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Frame, Spacer
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.pagesizes import A3, A4, landscape, portrait
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
from reportlab.pdfgen import canvas

pdfReportPages = "C:\\Temp\\test.pdf"
doc = SimpleDocTemplate(pdfReportPages, pagesize=A4)

# container for the "Flowable" objects
elements = []
styles=getSampleStyleSheet()
styleN = styles["Normal"]

# Make heading for each column and start data list
column1Heading = "COLUMN ONE HEADING"
column2Heading = "COLUMN TWO HEADING"
# Assemble data for each column using simple loop to append it into data list
data = [[column1Heading,column2Heading]]
for i in range(1,100):
    data.append([str(i),str(i)])

tableThatSplitsOverPages = Table(data, [6 * cm, 6 * cm], repeatRows=1)
tableThatSplitsOverPages.hAlign = 'LEFT'
tblStyle = TableStyle([('TEXTCOLOR',(0,0),(-1,-1),colors.black),
                       ('VALIGN',(0,0),(-1,-1),'TOP'),
                       ('LINEBELOW',(0,0),(-1,-1),1,colors.black),
                       ('BOX',(0,0),(-1,-1),1,colors.black),
                       ('BOX',(0,0),(0,-1),1,colors.black)])
tblStyle.add('BACKGROUND',(0,0),(1,0),colors.lightblue)
tblStyle.add('BACKGROUND',(0,1),(-1,-1),colors.white)
tableThatSplitsOverPages.setStyle(tblStyle)
elements.append(tableThatSplitsOverPages)

doc.build(elements)

Ответ 3

Я нашел это решение, чтобы легко повторить заголовок таблицы, которая находится на двух страницах. Добавьте эту строку в свой CSS для своей таблицы:

-fs-table-paginate: paginate;

Я также нашел класс для FPDF, который кажется мощным (мне он не нужен на данный момент, поэтому я его не тестировал)

http://interpid.eu/fpdf-table