在Python(Django)中将PDF转换为二进制
我需要把一个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。如果是这样的话,这个回答可能正是你需要的。下面是他解决方案的总结:
- 使用PdfFileReader()读取你的PDF,我们称之为input
- 使用ReportLab创建一个包含你要添加文本的新PDF,并将其保存为一个字符串对象
- 使用PdfFileReader()读取这个字符串对象,我们称之为text
- 使用PdfFileWriter()创建一个新的PDF对象,我们称之为output
- 遍历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'
根据最终的输出,你可以判断:
- 它是否是一个PDF
- 如果是的话,如何应用你想要的更改或与当前的PDF文档合并。
- 如果不是,如何将内容写入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