【问题标题】:How to Repeat Table Column Headings over Page Breaks in PDF output from ReportLab如何在 ReportLab 的 PDF 输出中的分页符上重复表格列标题
【发布时间】:2012-03-05 11:53:15
【问题描述】:

我正在使用 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)

【问题讨论】:

    标签: pdf-generation reportlab platypus


    【解决方案1】:

    这是我在遵循 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)
    

    【讨论】:

      【解决方案2】:

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

      repeatRows 参数指定前导行数 当要求 Table 自行拆分时,应重复此操作。

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

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

      【讨论】:

      • 谢谢 Gordon - 让我回到手册,让我能够开发一个更简单且有效的代码示例,我将在下面添加作为答案。
      【解决方案3】:

      在创建表格时使用 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
      

      【讨论】:

        【解决方案4】:

        t1 = 表(列表,colWidths=220,rowHeights=20,repeatRows=1) 只需输入 repeatRows=1

        【讨论】:

          【解决方案5】:

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

          -fs-table-paginate: 分页;

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

          http://interpid.eu/fpdf-table

          【讨论】:

          • 感谢您的建议,但就我而言,我没有使用 CSS - 除非那只是在后台发生。
          猜你喜欢
          • 2016-03-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-01
          • 2017-01-05
          • 1970-01-01
          • 2012-03-30
          • 1970-01-01
          相关资源
          最近更新 更多