Django HTML & CSS 渲染为 pdf
Posted
技术标签:
【中文标题】Django HTML & CSS 渲染为 pdf【英文标题】:Django HTML & CSS render to pdf 【发布时间】:2020-04-12 13:33:46 【问题描述】:我正在尝试使用 Django-weasyprint 将 html 和 CSS 转换为 pdf 页面,但我有点坚持他们的教程,因为我希望 PDF 在用户单击下载按钮时呈现当前页面并且 pdf 会以只读权限自动下载。整个过程感觉很痛苦。
目前weasyprint只是将Django中的一个URL转成pdf,但是不知道怎么设置按钮查看weasyprint视图。
也许我正在回顾它并且过于复杂化,任何帮助将不胜感激。
Weasyprints 示例代码:
from django.conf import settings
from django.views.generic import DetailView
from django_weasyprint import WeasyTemplateResponseMixin
from django_weasyprint.views import CONTENT_TYPE_PNG
class MyModelView(DetailView):
# vanilla Django DetailView
model = MyModel
template_name = 'mymodel.html'
class MyModelPrintView(WeasyTemplateResponseMixin, MyModelView):
# output of MyModelView rendered as PDF with hardcoded CSS
pdf_stylesheets = [
settings.STATIC_ROOT + 'css/app.css',
]
# show pdf in-line (default: True, show download dialog)
pdf_attachment = False
# suggested filename (is required for attachment!)
pdf_filename = 'foo.pdf'
class MyModelImageView(WeasyTemplateResponseMixin, MyModelView):
# generate a PNG image instead
content_type = CONTENT_TYPE_PNG
# dynamically generate filename
def get_pdf_filename(self):
return 'bar-at.pdf'.format(
at=timezone.now().strftime('%Y%m%d-%H%M'),
)
我在我的电脑上创建了一个虚拟环境,它的设置与示例完全相同。目前使用的是 Boostrap 4。
*编辑如果有更好的方法,非常欢迎你分享:)
我还想只针对正文标签,以便它只将该部分转换为 pdf 而不是整个页面。
在此之前我使用的解决方案是:https://codepen.io/AshikNesin/pen/KzgeYX,但这不是很好。
*编辑 2.0
我已经转向 js 并且我被这个脚本困住了,它不想在 click 函数上创建 pdf 表单 还有一种方法可以将 js 函数设置为仅下载选定的 Id 在div 而不是一定规模? (怕是要用分辨率而不是实际需要渲染的内容)
https://jsfiddle.net/u4ko9pzs/18/
任何建议将不胜感激。
【问题讨论】:
【参考方案1】:您不需要使用该 django 应用程序。您可以按照博客文章https://www.bedjango.com/blog/how-generate-pdf-django-weasyprint/中的示例编写自定义视图来处理打印
我发现该应用程序存在限制并编写了我自己的观点。没那么难。
【讨论】:
为什么说它的限制?你想达到什么目标? weasyprint 给出了 cario 依赖错误:/ 如果你安装了 cario,它仍然不起作用 weasyprint instalation instruction 肯定有更简单的方法来呈现 pdf :) @Robert 对于我来说,Linux 和 Mac 的终端都是 2 行。至于Windows,我不知道,但我敢肯定这不是微不足道的 @somecallitblues 我在使用 GTK 时遇到的问题不记得详细了,但是因为 shure 不是 Windows 上安装的第一个选项。 MSYS2 版本不起作用(某些 Windows 服务已运行,安装过程中安装不会更改此行为)。但他们发布了maintened version,这很有效。【参考方案2】:我试过 django-wkhtmltopdf 和 weasyprint。对于舒尔 weasyprint 允许更多的 css 主题,但它仍然不是一对一的浏览器版本。我对结果不满意。 对于表格和所有类似 word/excel 的数据都可以。但在我的情况下,我必须制作 px 到 px 的“证书”,比如带有 svg 形状背景的 pdf 然后一些缺乏功能开始成为不方便的问题。
因此,如果您需要使用相同的 css 并进行最少的修改以像在浏览器中一样获得效果,那么 puppeter 可以解决所有兼容性问题。但是这股力量要使用 Node 来运行 puppeteer。 (就我而言,我已经用它来编译资产)
Cli for puppetere:
npm i- puppeteer-pdf
then install wrapper
pip install django-puppeteer-pdf
在设置中添加节点 puppeteer cli 启动命令:
PUPPETEER_PDF_CMD = 'npx puppeteer-pdf'
并创建视图
from puppeteer_pdf import render_pdf_from_template
from django.http import HttpResponse,
import os
# Rendering code
context =
'data': 'test data'
output_temp_file = os.path.join(settings.BASE_DIR, 'static', 'temp.pdf')
pdf = render_pdf_from_template(
input_template='path to template in templates dir'
header_template='',
footer_template='',
context=context,
cmd_options=
'format': 'A4',
'scale': '1',
'marginTop': '0',
'marginLeft': '0',
'marginRight': '0',
'marginBottom': '0',
'printBackground': True,
'preferCSSPageSize': True,
'output': output_temp_file,
'pageRanges': 1
)
#you can remove temp file now or collecte them and run some crone task.(performance)
if os.path.exists(output_temp_file):
os.remove(output_temp_file)
else:
# raise error or something
filename = f'filename='your donwload file name'.pdf'
response = HttpResponse(pdf, content_type='application/pdf;')
response['Content-Disposition'] = filename
要保持原始颜色,您必须添加
html
-webkit-print-color-adjust: exact;
当您选择“preferCSSPageSize”时控制页面大小和边距。
@page
size: A4;
margin: 0 0 0 0;
【讨论】:
【参考方案3】:使用whkhtmltopdf
,它在 Django 中非常容易使用。它提供纯 html 生成的 PDF 转换
pip install django-wkhtmltopdf
https://django-wkhtmltopdf.readthedocs.io/en/latest/
【讨论】:
以上是关于Django HTML & CSS 渲染为 pdf的主要内容,如果未能解决你的问题,请参考以下文章