19

我正在使用 ReportLab 在 PDF 文档中编写表格,并且对结果非常满意(尽管还没有完全掌握 flowables)。

但是,我无法弄清楚如何使跨越分页符的表格重复其列标题。

下面的代码在 C:\Temp 中创建了一个 test.pdf,其中有一个标题行,后跟 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)
4

5 回答 5

22

这是我在遵循 Gordon 的建议重新考虑使用 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)
于 2012-02-15T04:19:19.713 回答
21

从文档中(是的,我知道,但有时很难在手册中找到这些东西):

repeatRows 参数指定当要求表拆分自身时应重复的前导行数。

因此,当您创建表时,这是您可以传递的参数之一,它将前 n 行转换为重复的标题行。您将在第 77 页找到这部分文本,但与创建表相关的部分从第 76 页开始。

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

于 2012-02-14T18:47:24.917 回答
6

创建表时使用 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
于 2018-06-21T20:50:25.720 回答
0

t1 = Table(lista, colWidths=220, rowHeights=20, repeatRows=1) 只需输入 repeatRows=1

于 2020-12-04T15:59:11.773 回答
-3

我发现这个解决方案可以轻松地在两页上的表格上重复标题。在表格的 CSS 中添加这一行:

-fs-table-paginate:分页;

我还找到了一个看起来很强大的 FPDF 类(我暂时不需要它,所以我没有测试它)

http://interpid.eu/fpdf-table

于 2013-03-23T11:19:16.523 回答