python - 如何在 Reportlab Frame 中输入静态画布布局
问题描述
我正在尝试创建一个具有框架的文档,该框架可以从 Canvas 中获得定义的布局,然后对多个框架使用相同的格式。
所以理想情况下,这个框架将能够根据框架内的 Flowable 段落大小而增长。因此,每个帧中都会有一个不同类型的标题,然后是一个不同大小的段落。我一直在与试图弄清楚这一点的文档对抗。我的框架也应该一个在另一个之上。因此,根据大小,如果页面上有一个 Frame 并且段落中有很多文本,则可能只有一个 Frame 适合页面。但是,如果有两个框架的段落足够小,那么这两个框架将适合一页。
对于它的价值,这是我开始的一些代码:
from reportlab.platypus import BaseDocTemplate, Frame, Paragraph, NextPageTemplate, PageBreak, \
PageTemplate, NextFrameFlowable
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.pagesizes import landscape, letter
from reportlab.rl_config import defaultPageSize
from reportlab.lib.units import mm, inch
from reportlab.lib.colors import *
from reportlab.platypus import Paragraph, Frame, Spacer, SimpleDocTemplate
styles = getSampleStyleSheet()
logo_image = r'C:\Users\user\Desktop\FlaskReportApp\application\static\images\logo.JPG'
doc = BaseDocTemplate('basedoc.pdf', defaultPageSize=letter, showBoundary=1)
def foot1(canvas, doc):
canvas.saveState()
canvas.setFont('Times-Roman', 14)
canvas.drawString(inch, 0.75 * inch, "Page %d" % doc.page)
canvas.drawImage(logo_image, 45, 685, width=150, preserveAspectRatio=True)
canvas.restoreState()
# Two Columns
frame1 = Frame(doc.leftMargin, inch*8, doc.width, inch*2, id='col1', showBoundary=1)
frame2 = Frame(doc.leftMargin, inch*5.5, doc.width, inch*2, id='col2', showBoundary=1)
template = PageTemplate(id='TwoBoxKeystroke', frames=[frame1, frame2], onPage=foot1)
doc.addPageTemplates([template])
story = []
story.append(Paragraph("Frame one box, " * 20, styles['Normal']))
story.append(Paragraph("Frame two box, " * 20, styles['Normal']))
doc.build(story)
您如何根据框架内不同的段落大小等因素准确地使框架的大小动态变化?
解决方案
框架通常位于给定类型的页面布局中的固定位置,并且正在使用的页面布局切换为偶数/奇数/第一/最后/章节页面。这种机制主要由 DocTemplate 操作,而无需了解 flowables 本身。
有一次我改变了这一点是通过插入一个platypus.NextPageTemplate('chapter-{}'.format(chapter))
流动的,通常紧跟在一个platypus.PageBreak()
允许你切换PageTemplate
到下一页使用的后面。
在我的例子中,NextPageTemplate
有一些画布级别的绘图(在可流动对象之外)以在外页叶子下方生成一个彩色标记,突出显示当前章节。它的工作方式如下:
- 使用
doc = platypus.BaseDocTemplate()
文档模板。 platypus.PageTemplate(frames=..., id=..., onPage=..)
为列表中的每一章创建一个,其中onPage
是一个可调用的,它在画布上呈现适当的标记,部分应用相同的 id。- 将所有 PageTemplates 添加到列表中并将其注册到
doc.addPageTemplates(templates)
PageTemplate
用于所有后续页面 的 id是platypus.NextPageTemplate(id)
也许您可以通过测量文本并提前设置模板来创建所需的布局。否则,您可能希望保持 Frames 固定(整页),并尝试在 Paragraph flowables 周围使用填充/边距来实现您想要的外观。
或者,它可能非常专业,以至于您自己将新页面扔到画布上并手动进行框架布局,并一次将一个段落附加到新框架并在画布上绘制它。
推荐阅读
- python-3.x - 如何将分隔符附加到刮掉的桌子上?
- c# - 如何从 2 个不同的字符串中获取字典中的值
- javascript - 如何计算摩纳哥差异编辑器中更改的行数?
- angular - 为什么http客户端请求返回错误作为字符串而不是HttpErrorResponse?
- laravel - 如何在 eloquent 中定义逆多态多对可能关系?
- python-3.x - 尝试通过 Web 套接字连接,它总是得到 HTTP/1.1 405 Method Not Allowed 错误
- azure - Azure 服务总线获取对消息的响应
- python - 如何有效地调用另一个函数或另一个进程而不等待响应
- php - 如何在一个数组中组合多个变量
- php - 当我试图获取用户 IP 时出现奇怪的代码