【问题标题】:Django HTML & CSS render to pdfDjango HTML & CSS 渲染为 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/

任何建议将不胜感激。

【问题讨论】:

    标签: javascript html css django bootstrap-4


    【解决方案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/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-06
        • 2010-11-25
        • 2018-02-16
        • 2010-09-30
        • 2018-04-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多