Python 使用reportlabs将临时图像写入金字塔中的临时pdf

Python 使用reportlabs将临时图像写入金字塔中的临时pdf,python,pdf,pdf-generation,pyramid,reportlab,Python,Pdf,Pdf Generation,Pyramid,Reportlab,我正在使用Python3、pyramid和reportlabs来生成动态PDF 我在将图像写入pdf时遇到问题。我在web中使用Reportlab生成带有图像的pdf,因为我的图像不是本地存储的,而是在远程服务器上。我正在本地下载它们到它们保存的临时目录中,当我将图像添加到pdf中时,我已经检查过了,它们正在分配空间,但图像没有显示 以下是我的相关代码: # creates pdf in memory doc = SimpleDocTemplate(pdfName, pa

我正在使用Python3、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)
我在这里遵循了用户指南,并尝试了上述方法,以及用户指南在段落部分中所述的嵌入图像,并将图像放在表格中

我也看了看:这对我没有帮助

我的问题是,下载图片并放入pdf的正确方式是什么

编辑:固定代码缩进

编辑2:

答:我终于要把这些图片放进PDF了。我不确定是什么触发了它的工作。我所知道的唯一改变是现在我正在使用urllib来执行请求,而在此之前我没有这样做。以下是我的工作代码,仅针对问题进行了简化,这在我的代码中更为抽象和封装:

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)

使代码独立于文件的来源。将文件/资源检索与文档生成分开。确保工具集正在使用本地文件。封装代码以在加载程序类或函数中加载文件。封装才是最重要的。本周在查看loader类时再次注意到了这一点。 如果这是可行的,那么您知道reportlab、PIL和您的应用程序基本上是可行的

然后让您的代码使用类似URI的URI处理远程文件http://path/to/remote/files.

之后,您可以根据环境或用例从使用文件加载程序或httploader切换

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

这样,当从本地切换到远程时,唯一改变的就是URL。可能您需要一个python库来支持这一点。库非常适合下载东西,很可能它还支持URL scheme file://文件。

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

使用版本3.1.8的reportlab.platypus.flowables.py

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)
        ...
代码示例的最后三行告诉您可以传递具有读取方法的对象。这正是调用urllib.request.urlopenurl返回的结果。使用该内存缓冲区可以创建映像的实例。不需要对文件系统具有写访问权限,也不需要在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)
参考资料


我添加了reportlab标记。什么图像格式?如果图像格式不是.jpeg.GIF、PNG和JPG,则需要安装PIL。是的,我已经安装了PIL。请修复从第6行开始的代码示例缩进是的,我知道代码封装,这只是清理和重构之前的代码片段。谢谢您的建议和见解,但这并不能解决我的问题。我并不是想强调封装。你问了一个关于两项任务的问题,我建议将事情分解以降低复杂性。顺便说一句,如果有人想复制你的python环境,pip冻结可能会很有趣。这里有一个链接我的pip冻结,我也接受了你的建议,并将其分解。当不在临时目录中工作时,我可以使用远程映像创建pdf。因此,这让我相信,在呈现pdf和清理目录时,可能存在竞争条件。但我仍在研究它。请毫不犹豫地扩展您的代码示例。当前版本缺少有关临时文件实现详细信息和触发PDF呈现的上下文详细信息。全部粘贴,我的鼠标有一个滚轮。