我正在尝试为我的客户创建一个PDF来开始为他们的客户开具发票。我曾经处理过创建PDF的问题,并且记住创建它们是一件巨大的痛苦。在我的Django应用程序中,我有两个视图函数,一个只是渲染我用来设计发票的模板,另一个将它转换为pdf并渲染PDF。我有两个并排打开的标签,指向每个版本模板HTML与PDF,它们看起来完全不同。是否有一种特殊的标记语言我必须使用它来创建PDF,或者它们是一个python包,它将HTML转换为PDF中该HTML的精确副本?
查看功能
from django.shortcuts import render, HttpResponse
from django.template.loader import get_template
from io import BytesIO
from xhtml2pdf import pisa
def generate_pdf(template_src, context_dict={}):
template = get_template(template_src)
html = template.render({})
result = BytesIO()
pdf = pisa.pisaDocument(BytesIO(html.encode("ISO-8859-1")), result)
if not pdf.err:
return HttpResponse(result.getvalue(), content_type='application/pdf')
return None
def ronin(request):
template = get_template('ronin.html')
context = {}
html = template.render(context)
pdf = generate_pdf('ronin.html', context)
if pdf:
response = HttpResponse(pdf, content_type='application/pdf')
filename = "Invoice_%s.pdf" % ("12341231")
content = "inline; filename='%s'" % (filename)
download = request.GET.get("download")
if download:
content = "attachment; filename='%s'" % (filename)
response['Content-Disposition'] = content
return response
return HttpResponse("Not found")
def ronin_html(request):
template = 'ronin.html'
context = {}
return render(request, template, context)
HTML
<!DOCTYPE html>
<html>
<head></head>
<body style="margin: 0;">
<style>
#invoice-template {
padding: 100px 100px 50px 100px
}
table {
border-collapse: collapse;
}
table#main {
border-bottom: 1px solid darkgray; width: 100%;
}
td.header.first {
border-bottom: 1px solid darkgray;
border-right: 1px solid darkgray;
padding: 1% 4%;
width: 20%;
}
td.header.second {
padding: 0;
vertical-align: top;
}
td.header.second .contact-details td {
padding: 15px;
}
td.header.second .address td {
padding: 15px;
}
td.header.second p {
margin: 0;
}
</style>
<div id="invoice-template">
<table id="main" cellspacing="0">
<tr>
<td class="header first">
<img src="/static/images/logo_dark.png" alt="">
</td>
<td class="header second">
<table>
<tr class="address">
<td>
<p>ADDRESS</p>
<p>ADDRESS EXAMPLE St. CITY, STATE 11111</p>
</td>
</tr>
<tr class="contact-details">
<td>
<p>PHONE</p>
<p>+1 111 222 3333</p>
</td>
<td>
<p>WEBSITE</p>
<p>Website.com</p>
</td>
<td>
<p>FOCUS</p>
<p>WEBSITES / MOBILE APPS</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
答案 0 :(得分:1)
您可能会遇到大多数HTML到PDF库的渲染问题,特别是如果他们使用WebKit作为引擎。我推荐使用Puppeteer的组合(用于创建页面的无头chrome实例并截取屏幕截图,这将是页面的真正1:1复制品)和PDFKit来获取这些图像并将它们附加到pdf文件。
当然,这取决于您知道发票不会比完整的PDF页面大,或者如果它们是,您需要知道如何将内容分成单独的页面。
如果您真的想要PDF格式的1:1复制品,那些难题需要解决。
否则,我建议使用像wkhtmltopdf这样的东西来获得相当不错的近似值。