Reportlab Platypus 在第二次生成空文件

发布于 2025-01-13 20:57:28 字数 755 浏览 0 评论 0原文

最简单的例子:

import io

import lorem
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import SimpleDocTemplate, Paragraph

styles = getSampleStyleSheet()
story = [Paragraph(lorem.text(), styles["Normal"])]

with io.BytesIO() as out:
    doc = SimpleDocTemplate(out)
    doc.build(story) # here, you can replace story with story[:] to fix it

with open("test.pdf", "wb+") as out:
    doc = SimpleDocTemplate(out)
    doc.build(story[:])

上面的代码生成一个空的PDF文件(960字节,没有内容,白色的空页)。如果在第一个 (BytesIO) 块中将 build(story) 替换为 build(story[:]),则 test .pdf 文件在第二个(open 文件)块中正确生成。

为什么?

(Windows 上的 Python 3.9.0 amd64,reportlab 3.5.65)

Minimal example:

import io

import lorem
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import SimpleDocTemplate, Paragraph

styles = getSampleStyleSheet()
story = [Paragraph(lorem.text(), styles["Normal"])]

with io.BytesIO() as out:
    doc = SimpleDocTemplate(out)
    doc.build(story) # here, you can replace story with story[:] to fix it

with open("test.pdf", "wb+") as out:
    doc = SimpleDocTemplate(out)
    doc.build(story[:])

The above code generates an empty PDF file (960 bytes, no content, white empty page). If you replace build(story) with build(story[:]) in the first (BytesIO) block, then the test.pdf file is generated correctly in the second (open file) block.

Why?

(Python 3.9.0 amd64 on Windows, reportlab 3.5.65)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心是晴朗的。 2025-01-20 20:57:28

答案是故事被 doc.build 消耗。当您构建文档时,故事中的内部对象会发生更改,并且它们不能重复用于构建另一个文档。我认为它没有记录在任何地方。使用浅拷贝是不够的,它很可能最终会出现 reportlab.platypus.doctemplate.LayoutError 错误“Flowable 太大”。

当您想要多次渲染故事时,最安全的解决方案是始终使用深层副本:

import copy
doc.build(copy.deepcopy(story))

The answer is that the story is consumed by doc.build. When you build a document, then the internal objects are changed inside your story, and they cannot be reused for bulding another document. I think it is not documented anywhere. Using a shallow copy is not enough, it will most likely end up in a reportlab.platypus.doctemplate.LayoutError error "Flowable too large".

The safest solution is to always use a deep copy, when you want to render a story multiple times:

import copy
doc.build(copy.deepcopy(story))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文