Как повторять заголовки столбцов таблицы поверх разрывов страниц в выводе 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)

person PolyGeo    schedule 14.02.2012    source источник


Ответы (5)


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

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

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

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

person G Gordon Worley III    schedule 14.02.2012
comment
Спасибо, Гордон, - указав мне на руководство, я смог разработать гораздо более простой и рабочий пример кода, который я добавлю в качестве ответа ниже. - person PolyGeo; 15.02.2012

Это код, который я разработал, следуя совету Гордона пересмотреть использование 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)
person PolyGeo    schedule 15.02.2012

Используйте repeatRows=1 при создании таблицы...

from reportlab.platypus import Table 
Table(data,repeatRows=1)

Мне всегда нравится иметь что-то, что можно вырезать и вставить в файл .py для запуска и тестирования. Так вот...

import os
import pandas as pd
import numpy as np
import reportlab.platypus 
import reportlab.lib.styles
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.lib.pagesizes import letter, landscape

reportoutputfilepath = os.path.join('.\\test.pdf')

pdf_file = reportlab.platypus.SimpleDocTemplate(
                            reportoutputfilepath,
                            pagesize=landscape(letter),
                            rightMargin=10,
                            leftMargin=10,
                            topMargin=38,
                            bottomMargin=23
                    )
ts_tables = [
         ('ALIGN', (4,0), (-1,-1), 'RIGHT'),
         ('LINEBELOW', (0,0), (-1,0), 1, colors.purple),
         ('FONT', (0,0), (-1,0), 'Times-Bold'),
         ('LINEABOVE', (0,-1), (-1,-1), 1, colors.purple),
         ('FONT', (0,-1), (-1,-1), 'Times-Bold'),
         ('BACKGROUND',(1,1),(-2,-2),colors.white),
         ('TEXTCOLOR',(0,0),(1,-1),colors.black),
         ('FONTSIZE', (0,0),(-1,-1), 8), 
         ]

df = pd.DataFrame(np.random.randint(0,1000,size=(1000, 4)), columns=list('ABCD'))
lista = [df.columns[:,].values.astype(str).tolist()] + df.values.tolist()

#Here is where you put repeatRows=1
table = reportlab.platypus.Table(lista, colWidths=(20*mm, 20*mm, 20*mm, 20*mm),repeatRows=1)
table_style = reportlab.platypus.TableStyle(ts_tables)
table.setStyle(table_style)
elements = []
elements.append(table)

# Build the PDF
pdf_file.build(elements)
print reportoutputfilepath
person Justin Malinchak    schedule 21.06.2018

t1 = Таблица (список, colWidths = 220, rowHeights = 20, RepeatRows = 1) просто введите repeatRows = 1

person Mamta Chaudhary    schedule 04.12.2020

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

-fs-table-paginate: разбить на страницы;

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

http://interpid.eu/fpdf-table

person bastien    schedule 23.03.2013
comment
Спасибо за предложение, но в моем случае я не использую CSS, если только это не происходит в фоновом режиме. - person PolyGeo; 29.04.2013