python - 在 Pyramid 中使用 reportlabs,将临时图像写入临时 pdf

  显示原文与译文双语对照的内容
0 0

我使用 python 3,Pyramid 和reportlabs来生成动态 pdf 。

我将图像写入pdf时出现问题。 我在web中使用Reportlab生成一个带图像的pdf,我的图像不存储在本地,它们在远程服务器上。 我将它们下载到一个临时目录( 他们在保存我已经检查过了) 当我去添加图像到 pdf,它们的空间分配但图像没有显示。

下面是我的相关代码( 简化):

 # creates pdf in memory
 doc = SimpleDocTemplate(pdfName, pagesize=A4)
 elements = []
 for item in model['items']:
 # image goes here:
 if item['IMAGENAME']:
 response = getImageFromRemoteServer(item['IMAGENAME'])
 dir_filename = directory + item['IMAGENAME']
 if response.status_code == 200:
 with open(dir_filename, 'wb') as f:
 for chunk in response.iter_content():
 f.write(chunk)
 questions.append(Image(dir_filename, width=2*inch, height=2*inch))
 # create and save the pdf
 doc.build(elements,canvasmaker=NumberedCanvas)

我已经按照这里的用户指南 https://www.reportlab.com/docs/reportlab-userguide.pdf,并尝试了上述方法,加上嵌入式图像( 就像用户指南在段落部分中所说) 并将图像放在表格中。

我在这里也看到了 : 并没有帮助我。

我的问题是,如何下载图像并放入pdf是正确的?

编辑:固定代码缩进

编辑2:

最后,我终于得到了PDF中的图像。 我不确定是什么触发了它。 唯一知道我改变的是现在我正在使用mtf来完成请求,然后在没有变化之前。 下面是我的工作代码( 只有在我的代码中对问题进行了抽象和封装。):

doc = SimpleDocTemplate(pdfName, pagesize=A4)
# array of elements in the pdf
elements = []
for question in model['questions']:
 # image goes here:
 if question['IMAGEFILE']:
 filename = question['IMAGEFILE']
 dir_filename = directory + filename
 url = get_url(settings, filename)
 response = urllib.request.urlopen(url)
 raw_data = response.read() 
 f = open(dir_filename, 'wb')
 f.write(raw_data)
 f.close()
 response.close()
 myImage = Image(dir_filename)
 myImage.drawHeight = 2* inch
 myImage.drawWidth = 2* inch
 myImage.hAlign ="LEFT"
 elements.append(myImage)
# create and save the pdf
doc.build(elements)
时间:原作者:6个回答

0 0

使你的代码独立于文件的来源。 将文件/资源检索从文档生成中分离。 确保你的工具集正在处理本地文件。 封装代码以加载加载程序类或者函数中的文件。 封装是重要的。 本周再次注意 thumbor加载器类时请注意这个问题。 如果那样工作,你知道reportlab和你的应用程序基本上是工作的。

然后使用 http://path/to/remote/files 像一样使用远程文件处理代码。

之后,你可以根据环境或者用例使用你的或者你的httploader 。

另一个选择是让你的代码使用像 file://path/to/file 这样的URI处理本地文件

这样,当从本地切换到远程时,唯一改变的是 URL 。 也许你需要一个 python 库来支持这个。 请求库非常适合下载东西,很可能它也支持URL方案 file://

原作者:
0 0

最可能的lazy 参数是你的第一个代码样本没有渲染图像。 在临时文件的上下文管理器之外触发 reportlab PDF呈现可能导致这种行为。

reportlab.platypus.flowables.py ( 使用版本 3.1.8 )

class Image(Flowable):
"""an image (digital picture). Formats supported by PIL/Java 1.4 (the Python/Java Imaging Library
 are supported. At the present time images as flowables are always centered horozontally
 in the frame. We allow for two kinds of lazyness to allow for many images in a document
 which could lead to file handle starvation.
 lazy=1 don't open image until required.
 lazy=2 open image when required then shut it.
"""
 _fixedWidth = 1
 _fixedHeight = 1
 def __init__(self, filename, width=None, height=None, kind='direct', mask="auto", lazy=1):
"""If size to draw at not specified, get it from the image."""
 self.hAlign = 'CENTER'
 self._mask = mask
 fp = hasattr(filename,'read')
 if fp:
 self._file = filename
 self.filename = repr(filename)
. . .

代码示例的最后三行告诉你可以传递具有 read 方法的对象。 这正是对 urllib.request.urlopen(url)的调用的结果。 使用内存缓冲区创建一个图像实例。 无需对 文件系统 有写访问权限,不需要在PDF呈现后删除这些文件。 应用我们的新知识提高代码可读性。 由于用例包括使用支持 python 文件API的远程资源检索,因这里可以以更清晰地组装PDF文件。

from contextlib import closing
import urllib.request
doc = SimpleDocTemplate(pdfName, pagesize=A4)
# array of elements in the pdf
elements = []
for question in model['questions']:
 # download image and create Image from file-like object
 if question['IMAGEFILE']:
 filename = question['IMAGEFILE']
 image_url = get_url(settings, filename)
 with closing(urllib.request.urlopen(image_url)) as image_file:
 myImage = Image(image_file, width=2*inch, height=2*inch)
 myImage.hAlign ="LEFT"
 elements.append(myImage)
# create and save the pdf
doc.build(elements)

引用

  • 带有上下文管理器的代码
原作者:
...