在Python(Django)中将PDF转换为二进制

-1 投票
2 回答
2130 浏览
提问于 2025-04-18 07:53

我需要把一个PDF文件发送到浏览器,而这个PDF是从一个API以二进制格式返回的。

我使用的是Python 2.7和Django 1.5,还有requests库。

我按照Django文档里的建议,安装了ReportLab库。我还成功运行了下面这个例子:

response = HttpResponse(content_type="application/pdf")
response["Content-Disposition"] = "inline; filename=a_test_document.pdf"

p = canvas.Canvas(response)

p.drawString(100, 500, "Hello world")

p.showPage()
p.save()

return response

不过,这个例子只是让我能在我自己的PDF上绘图。请问有没有办法把二进制数据转换成PDF文件呢?我查阅了ReportLab的文档和其他一些解决方案,但没有找到明确的答案。

2 个回答

0

看起来你想要更新一个已经存在的PDF,而不是简单地创建一个新的PDF。如果是这样的话,这个回答可能正是你需要的。下面是他解决方案的总结:

  1. 使用PdfFileReader()读取你的PDF,我们称之为input
  2. 使用ReportLab创建一个包含你要添加文本的新PDF,并将其保存为一个字符串对象
  3. 使用PdfFileReader()读取这个字符串对象,我们称之为text
  4. 使用PdfFileWriter()创建一个新的PDF对象,我们称之为output
  5. 遍历input,对你想要添加文本的每一页使用.mergePage(text.getPage(0)),然后用output.addPage()将修改后的页面添加到新文档中

另一方面,如果你不确定收到的二进制文件是什么类型(虽然根据你的例子不太可能,但还是值得提一下),你可以使用一个叫做python-magic的工具。这是一个未经测试的潜在示例:

In [2]: import magic
In [3]: m = magic.Magic(mime=True)
In [4]: m.from_file('/home/culebron/Documents/chapter2.pdf')
Out[4]: 'pdf'

根据最终的输出,你可以判断:

  1. 它是否是一个PDF
  2. 如果是的话,如何应用你想要的更改或与当前的PDF文档合并。
  3. 如果不是,如何将内容写入Canvas。
0

如果你想生成PDF文件,可以使用xhtml2pdf这个库。

这个函数会返回一个响应对象,你只需要传入你的模板名称、上下文数据和PDF文件名就可以了。

def fetch_resources(uri, rel):
    """
    Callback to allow xhtml2pdf/reportlab to retrieve Images,Stylesheets, etc.
    `uri` is the href attribute from the html link element.
    `rel` gives a relative path, but it's not used here.

    """
    if uri.startswith(settings.MEDIA_URL):
        path = os.path.join(settings.MEDIA_ROOT,
                            uri.replace(settings.MEDIA_URL, ""))
    elif uri.startswith(settings.STATIC_URL):
        path = os.path.join(settings.STATIC_ROOT,
                            uri.replace(settings.STATIC_URL, ""))
    else:
        path = os.path.join(settings.STATIC_ROOT,
                            uri.replace(settings.STATIC_URL, ""))

        if not os.path.isfile(path):
            path = os.path.join(settings.MEDIA_ROOT,
                                uri.replace(settings.MEDIA_URL, ""))

            if not os.path.isfile(path):
                raise UnsupportedMediaPathException(
                                    'media urls must start with %s or %s' % (
                                    settings.MEDIA_ROOT, settings.STATIC_ROOT))

    return path

def render_to_pdf_response(template_name, context=None, pdfname='test.pdf'):
  file_object = HttpResponse(mimetype='application/pdf')
  file_object['Content-Disposition'] = 'attachment; filename=%s' % pdfname
  template = get_template(template_name)
  html = template.render(Context(context))
  pisa.CreatePDF(html.encode("UTF-8"), file_object , encoding='UTF-8',
                 link_callback=fetch_resources)
  return file_object

这里是安装说明:https://pypi.python.org/pypi/xhtml2pdf/

撰写回答