[英]Dynamic framesize in Python Reportlab
我嘗試在 Python 中使用reportlab生成發貨清單。我試圖通過使用 Platypus Frames
將所有部分(如發件人地址、收件人地址、表格)放在適當的位置。
我遇到的第一個問題是我需要很多Frames
到 position 一切都正確,有沒有更好的方法使用 Platypus? 因為我希望發件人地址和我的地址在同一高度,如果我只是將它們添加到我的story = []
,它們就會一個一個地對齊。
下一個問題是我正在繪制的表格的大小是動態的,當我到達Frame
的末尾(我希望表格移動的空間)時,它只是在下一幀中執行FrameBreak
和連續。 那么我怎樣才能使Frame
(我的桌子的空間)動態化呢?
您的用例非常常見,因此Reportlab有一個系統可以幫助您。
如果您閱讀有關platypus
的用戶指南,它將向您介紹4個主要概念:
DocTemplates
文檔的最外層容器;
PageTemplates
各種頁面布局的規范;
Frames
中可包含流動文本或圖形的頁面區域的規范。
Flowables
使用PageTemplates
可以在例如像標志的,地址,這樣一個合理的方式組合頁上的“靜態”的內容與動態。
你已經發現了Flowables
和Frames
,但propably你沒有花哨的啟動PageTemplates
或DocTemplates
呢。 這是有道理的,因為大多數簡單文檔都沒有必要。 令人遺憾的是,發貨清單不是一個簡單的文件,它包含必須在每個頁面上的地址,徽標和重要信息。 這就是PageTemplates
。
那么你如何使用這些模板? 概念很簡單,每個頁面都有一定的結構可能會在頁面之間有所不同,例如在第一頁上要放置地址,然后在第二頁上啟動表格,只需要表格。 這將是這樣的:
示例如下所示:
(如果有一個Reportlab,這對SO文檔來說是完美的)
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import cm
from reportlab.lib import colors
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate, NextPageTemplate, Paragraph, PageBreak, Table, \
TableStyle
class ShippingListReport(BaseDocTemplate):
def __init__(self, filename, their_adress, objects, **kwargs):
super().__init__(filename, page_size=A4, _pageBreakQuick=0, **kwargs)
self.their_adress = their_adress
self.objects = objects
self.page_width = (self.width + self.leftMargin * 2)
self.page_height = (self.height + self.bottomMargin * 2)
styles = getSampleStyleSheet()
# Setting up the frames, frames are use for dynamic content not fixed page elements
first_page_table_frame = Frame(self.leftMargin, self.bottomMargin, self.width, self.height - 6 * cm, id='small_table')
later_pages_table_frame = Frame(self.leftMargin, self.bottomMargin, self.width, self.height, id='large_table')
# Creating the page templates
first_page = PageTemplate(id='FirstPage', frames=[first_page_table_frame], onPage=self.on_first_page)
later_pages = PageTemplate(id='LaterPages', frames=[later_pages_table_frame], onPage=self.add_default_info)
self.addPageTemplates([first_page, later_pages])
# Tell Reportlab to use the other template on the later pages,
# by the default the first template that was added is used for the first page.
story = [NextPageTemplate(['*', 'LaterPages'])]
table_grid = [["Product", "Quantity"]]
# Add the objects
for shipped_object in self.objects:
table_grid.append([shipped_object, "42"])
story.append(Table(table_grid, repeatRows=1, colWidths=[0.5 * self.width, 0.5 * self.width],
style=TableStyle([('GRID',(0,1),(-1,-1),0.25,colors.gray),
('BOX', (0,0), (-1,-1), 1.0, colors.black),
('BOX', (0,0), (1,0), 1.0, colors.black),
])))
self.build(story)
def on_first_page(self, canvas, doc):
canvas.saveState()
# Add the logo and other default stuff
self.add_default_info(canvas, doc)
canvas.drawString(doc.leftMargin, doc.height, "My address")
canvas.drawString(0.5 * doc.page_width, doc.height, self.their_adress)
canvas.restoreState()
def add_default_info(self, canvas, doc):
canvas.saveState()
canvas.drawCentredString(0.5 * (doc.page_width), doc.page_height - 2.5 * cm, "Company Name")
canvas.restoreState()
if __name__ == '__main__':
ShippingListReport('example.pdf', "Their address", ["Product", "Product"] * 50)
您可以使用 Platypus 的 KeepInFrame class 到 position 元素,例如在同一高度上的發送者和接收者的地址。 KeepInFrame 允許您指定您想要的元素的寬度和高度 position,它會自動調整元素的 position 以適應該空間。 以下是如何使用它的示例:
from reportlab.lib.units import cm
from reportlab.platypus import KeepInFrame
sender_address = "123 Main St, Anytown USA 12345"
receiver_address = "456 Park Ave, Anytown USA 67890"
# Create a KeepInFrame object with a width of 10cm and a height of 2cm
sender_address_frame = KeepInFrame(10*cm, 2*cm, [sender_address])
receiver_address_frame = KeepInFrame(10*cm, 2*cm, [receiver_address])
# Add the KeepInFrame objects to your story
story = [sender_address_frame, receiver_address_frame]
對於表格,您可以使用 KeepTogether 將表格的所有行保持在同一框架中。
from reportlab.platypus import KeepTogether
# Create a table
table = Table(data)
# Create a KeepTogether object with the table
table_frame = KeepTogether(table)
# Add
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.