Reportlab - Table 扩展到多个框架和页面
Reportlab - Table extend to multiple frames and pages
我正在尝试在 Reportlab 中创建一个简单的 table 来列出学生姓名。但是,此 table 超过 100 行,因此无法放在一页上。我正在寻找 table 当它变得太大而无法放在一页上时拆分,并在第二页上继续等等。我也在寻找 'Student Report:' 标题保留在每个页面的顶部。
我已经使用下面的代码来做到这一点,但是当我 运行 一个 table 大于一页的代码时,它 运行 无限期地。我希望有人可以帮助我。
提前一百万致谢,非常感谢!
import os
import pandas as pd
import numpy as np
from datetime import datetime as dt
from reportlab.pdfgen.canvas import Canvas
from reportlab.pdfgen import canvas
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib import colors
from reportlab.platypus import Paragraph, Frame, Table, TableStyle, Image, Spacer
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
#Pull in Student Names
student_names = pd.read_csv("test_names.csv")
#Define table style
tblstyle = TableStyle([('INNERGRID', (0,0), (-1,-1), 0.25, colors.white),
('BOX', (0,0), (-1,-1), 0.25, colors.white),
('FONTSIZE', (0, 0), (-1, 0), 6),
('FONTSIZE', (0, 1), (-1, -1), 6),
('TEXTFONT', (0, 0), (-1, 0), 'Calibri-Bold'),
('TEXTFONT', (0, 1), (0, -1), 'Calibri-Bold'),
('TEXTFONT', (0, 1), (-1, -1), 'Calibri'),
('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
('TEXTCOLOR', (1, 1), (0, -1), colors.black),
('LEFTPADDING', (0, 0), (-1, -1), 1),
('RIGHTPADDING', (0, 0), (-1, -1), 1),
('TOPPADDING', (0, 0), (-1, -1), 0),
('BOTTOMPADDING', (0, 0), (-1, -1), 0),
('ROWBACKGROUNDS', (0, 0), (-1, -1), (colors.HexColor('#e8e9ec'), colors.HexColor('#CED1D6'))),
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#3A5675')),
('ALIGN', (0, 0), (-1, 0), 'CENTER'),
('ALIGN', (0, 1), (-1, -1), 'CENTER'),
('VALIGN', (0, 0), (-1, -1), 'BOTTOM'),
])
#Create a document
c = canvas.Canvas("student_list.pdf")
dtstring = dt.date.today().strftime("%B %d, %Y")
#create header on first page
c.drawString(55,750,"Student Report: "+dtstring)
c.line(50,740,530,740)
# turn datatable the table into a list of lists which is the format reportlab wants
data_summary = [pd.DataFrame(student_names).columns.values.tolist()] + pd.DataFrame(student_names).values.tolist()
# config the widths and heights of this specific table
colwidths_2 = [300] * len(data_summary)
rowheights_2 = [15] * len(data_summary)
# create table using the platypus Table object & set the style
tbl_summary = Table(data_summary,colwidths_2,rowheights_2,hAlign='LEFT', repeatRows=1)
tbl_summary.setStyle(tblstyle)
# Create frame empty story
frame = Frame(50, 15, 500, 700, showBoundary=1)
story = []
story.append(tbl_summary)
for t in story:
while frame.add(t, c) == 0:
frame.split(t, c)
frame = Frame(50, 15, 500, 700, showBoundary=1)
# save pdf
c.save()
os.startfile('student_list.pdf')
我认为您 运行 认为 canvas 是一个页面。您需要使用文档模板,以便可流动的内容在到达页面末尾时知道该做什么。
...我没有 Pandas 或 Numpy,所以我无法对此进行测试,第一页页眉和间隔符可能需要调整,但我想你想要这样的东西:
import os
import pandas as pd
import numpy as np
from datetime import datetime as dt
from reportlab.pdfgen.canvas import Canvas
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.lib.units import inch
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib import colors
from reportlab.platypus import Paragraph, Frame, Table, TableStyle, Image, Spacer, SimpleDocTemplate
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
# Pull in Student Names
student_names = pd.read_csv("test_names.csv")
# Define table style
tblstyle = TableStyle([('INNERGRID', (0, 0), (-1, -1), 0.25, colors.white),
('BOX', (0, 0), (-1, -1), 0.25, colors.white),
('FONTSIZE', (0, 0), (-1, 0), 6),
('FONTSIZE', (0, 1), (-1, -1), 6),
('TEXTFONT', (0, 0), (-1, 0), 'Calibri-Bold'),
('TEXTFONT', (0, 1), (0, -1), 'Calibri-Bold'),
('TEXTFONT', (0, 1), (-1, -1), 'Calibri'),
('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
('TEXTCOLOR', (1, 1), (0, -1), colors.black),
('LEFTPADDING', (0, 0), (-1, -1), 1),
('RIGHTPADDING', (0, 0), (-1, -1), 1),
('TOPPADDING', (0, 0), (-1, -1), 0),
('BOTTOMPADDING', (0, 0), (-1, -1), 0),
('ROWBACKGROUNDS', (0, 0), (-1, -1), (colors.HexColor('#e8e9ec'), colors.HexColor('#CED1D6'))),
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#3A5675')),
('ALIGN', (0, 0), (-1, 0), 'CENTER'),
('ALIGN', (0, 1), (-1, -1), 'CENTER'),
('VALIGN', (0, 0), (-1, -1), 'BOTTOM'),
])
# Create a document
c = canvas.Canvas("student_list.pdf")
# turn datatable the table into a list of lists which is the format reportlab wants
data_summary = [pd.DataFrame(student_names).columns.values.tolist()] + pd.DataFrame(student_names).values.tolist()
# config the widths and heights of this specific table
colwidths_2 = [300] * len(data_summary)
rowheights_2 = [15] * len(data_summary)
# create table using the platypus Table object & set the style
tbl_summary = Table(data_summary, colwidths_2, rowheights_2, hAlign='LEFT', repeatRows=1)
tbl_summary.setStyle(tblstyle)
# Build Story - Add a spacer at the beginning for your heading
story = [
Spacer(1, 1 * inch)
]
story.append(tbl_summary)
# Create Page 1 Formatting
def myFirstPage(canvas: canvas.Canvas, doc):
canvas.saveState()
dtstring = dt.date.today().strftime("%B %d, %Y")
# create header on first page
canvas.drawString(55, 750, "Student Report: " + dtstring)
canvas.line(50, 740, 530, 740)
# Use a Document Template so the flowable can flow to the next page.
doc = SimpleDocTemplate(
"student_list.pdf",
pageSize=letter,
rightMargin=0.5 * inch, leftMargin=0.5 * inch, topMargin=0.5 * inch, bottomMargin=0.5 * inch,
)
# Build and save
doc.build(story, onFirstPage=myFirstPage)
编辑:将 link 添加到关于跨多个页面布局的好答案:
我正在尝试在 Reportlab 中创建一个简单的 table 来列出学生姓名。但是,此 table 超过 100 行,因此无法放在一页上。我正在寻找 table 当它变得太大而无法放在一页上时拆分,并在第二页上继续等等。我也在寻找 'Student Report:' 标题保留在每个页面的顶部。
我已经使用下面的代码来做到这一点,但是当我 运行 一个 table 大于一页的代码时,它 运行 无限期地。我希望有人可以帮助我。
提前一百万致谢,非常感谢!
import os
import pandas as pd
import numpy as np
from datetime import datetime as dt
from reportlab.pdfgen.canvas import Canvas
from reportlab.pdfgen import canvas
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib import colors
from reportlab.platypus import Paragraph, Frame, Table, TableStyle, Image, Spacer
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
#Pull in Student Names
student_names = pd.read_csv("test_names.csv")
#Define table style
tblstyle = TableStyle([('INNERGRID', (0,0), (-1,-1), 0.25, colors.white),
('BOX', (0,0), (-1,-1), 0.25, colors.white),
('FONTSIZE', (0, 0), (-1, 0), 6),
('FONTSIZE', (0, 1), (-1, -1), 6),
('TEXTFONT', (0, 0), (-1, 0), 'Calibri-Bold'),
('TEXTFONT', (0, 1), (0, -1), 'Calibri-Bold'),
('TEXTFONT', (0, 1), (-1, -1), 'Calibri'),
('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
('TEXTCOLOR', (1, 1), (0, -1), colors.black),
('LEFTPADDING', (0, 0), (-1, -1), 1),
('RIGHTPADDING', (0, 0), (-1, -1), 1),
('TOPPADDING', (0, 0), (-1, -1), 0),
('BOTTOMPADDING', (0, 0), (-1, -1), 0),
('ROWBACKGROUNDS', (0, 0), (-1, -1), (colors.HexColor('#e8e9ec'), colors.HexColor('#CED1D6'))),
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#3A5675')),
('ALIGN', (0, 0), (-1, 0), 'CENTER'),
('ALIGN', (0, 1), (-1, -1), 'CENTER'),
('VALIGN', (0, 0), (-1, -1), 'BOTTOM'),
])
#Create a document
c = canvas.Canvas("student_list.pdf")
dtstring = dt.date.today().strftime("%B %d, %Y")
#create header on first page
c.drawString(55,750,"Student Report: "+dtstring)
c.line(50,740,530,740)
# turn datatable the table into a list of lists which is the format reportlab wants
data_summary = [pd.DataFrame(student_names).columns.values.tolist()] + pd.DataFrame(student_names).values.tolist()
# config the widths and heights of this specific table
colwidths_2 = [300] * len(data_summary)
rowheights_2 = [15] * len(data_summary)
# create table using the platypus Table object & set the style
tbl_summary = Table(data_summary,colwidths_2,rowheights_2,hAlign='LEFT', repeatRows=1)
tbl_summary.setStyle(tblstyle)
# Create frame empty story
frame = Frame(50, 15, 500, 700, showBoundary=1)
story = []
story.append(tbl_summary)
for t in story:
while frame.add(t, c) == 0:
frame.split(t, c)
frame = Frame(50, 15, 500, 700, showBoundary=1)
# save pdf
c.save()
os.startfile('student_list.pdf')
我认为您 运行 认为 canvas 是一个页面。您需要使用文档模板,以便可流动的内容在到达页面末尾时知道该做什么。
...我没有 Pandas 或 Numpy,所以我无法对此进行测试,第一页页眉和间隔符可能需要调整,但我想你想要这样的东西:
import os
import pandas as pd
import numpy as np
from datetime import datetime as dt
from reportlab.pdfgen.canvas import Canvas
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.lib.units import inch
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib import colors
from reportlab.platypus import Paragraph, Frame, Table, TableStyle, Image, Spacer, SimpleDocTemplate
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
# Pull in Student Names
student_names = pd.read_csv("test_names.csv")
# Define table style
tblstyle = TableStyle([('INNERGRID', (0, 0), (-1, -1), 0.25, colors.white),
('BOX', (0, 0), (-1, -1), 0.25, colors.white),
('FONTSIZE', (0, 0), (-1, 0), 6),
('FONTSIZE', (0, 1), (-1, -1), 6),
('TEXTFONT', (0, 0), (-1, 0), 'Calibri-Bold'),
('TEXTFONT', (0, 1), (0, -1), 'Calibri-Bold'),
('TEXTFONT', (0, 1), (-1, -1), 'Calibri'),
('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
('TEXTCOLOR', (1, 1), (0, -1), colors.black),
('LEFTPADDING', (0, 0), (-1, -1), 1),
('RIGHTPADDING', (0, 0), (-1, -1), 1),
('TOPPADDING', (0, 0), (-1, -1), 0),
('BOTTOMPADDING', (0, 0), (-1, -1), 0),
('ROWBACKGROUNDS', (0, 0), (-1, -1), (colors.HexColor('#e8e9ec'), colors.HexColor('#CED1D6'))),
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#3A5675')),
('ALIGN', (0, 0), (-1, 0), 'CENTER'),
('ALIGN', (0, 1), (-1, -1), 'CENTER'),
('VALIGN', (0, 0), (-1, -1), 'BOTTOM'),
])
# Create a document
c = canvas.Canvas("student_list.pdf")
# turn datatable the table into a list of lists which is the format reportlab wants
data_summary = [pd.DataFrame(student_names).columns.values.tolist()] + pd.DataFrame(student_names).values.tolist()
# config the widths and heights of this specific table
colwidths_2 = [300] * len(data_summary)
rowheights_2 = [15] * len(data_summary)
# create table using the platypus Table object & set the style
tbl_summary = Table(data_summary, colwidths_2, rowheights_2, hAlign='LEFT', repeatRows=1)
tbl_summary.setStyle(tblstyle)
# Build Story - Add a spacer at the beginning for your heading
story = [
Spacer(1, 1 * inch)
]
story.append(tbl_summary)
# Create Page 1 Formatting
def myFirstPage(canvas: canvas.Canvas, doc):
canvas.saveState()
dtstring = dt.date.today().strftime("%B %d, %Y")
# create header on first page
canvas.drawString(55, 750, "Student Report: " + dtstring)
canvas.line(50, 740, 530, 740)
# Use a Document Template so the flowable can flow to the next page.
doc = SimpleDocTemplate(
"student_list.pdf",
pageSize=letter,
rightMargin=0.5 * inch, leftMargin=0.5 * inch, topMargin=0.5 * inch, bottomMargin=0.5 * inch,
)
# Build and save
doc.build(story, onFirstPage=myFirstPage)
编辑:将 link 添加到关于跨多个页面布局的好答案: