2012-02-14 227 views
10

Estoy usando ReportLab para escribir tablas en documentos PDF y estoy muy satisfecho con los resultados (a pesar de no tener una comprensión total de flowables todavía).Cómo repetir encabezados de columna de tabla sobre saltos de página en salida PDF de ReportLab

Sin embargo, no he podido averiguar cómo hacer que una tabla que abarca un salto de página tenga sus encabezados de columna repetidos.

El siguiente código crea un test.pdf en C: \ Temp que tiene una fila de encabezado seguido de 99 filas de datos.

La fila del encabezado se ve muy bien en la primera página, pero me gustaría que repita en la parte superior de la segunda y tercera páginas.

Me entusiasma escuchar acerca de los enfoques que se han utilizado para lograr eso utilizando 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) 

Respuesta

11

De la documentación (sí, lo sé, pero a veces es difícil de localizar este material en el manual):

El argumento repeatRows especifica el número de filas principales que debe repetirse cuando se le pide a la Tabla que se divida.

Así que cuando crea la tabla, este es uno de los argumentos que puede pasar, y convertirá las primeras n filas en filas de encabezado que se repiten. Se encuentra esta parte del texto en la página 77, pero la sección relativa a la creación de una tabla comienza en la página 76.

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

+0

Gracias Gordon - me señala de nuevo en el manual de me ha llevado a ser capaz de desarrollar un ejemplo de código mucho más simple y funcional que añadiré como respuesta a continuación. – PolyGeo

15

Este es el código que he desarrollado, después de seguir el consejo de Gordon a reconsiderar el uso de repeatRows , ¡y funciona!

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

Encontré esta solución para repetir fácilmente el encabezado en una tabla que está en dos páginas. Agregue esta línea en su CSS para su tabla:

-fs-table-paginate: paginate;

También encontré una clase para FPDF que parece potente (i no lo necesito, por el momento, así que no probarlo)

http://interpid.eu/fpdf-table

+0

Gracias por la sugerencia, pero en mi caso no estoy usando CSS, a menos que eso ocurra en segundo plano. – PolyGeo

Cuestiones relacionadas