简体   繁体   English

python cgi html pdf

[英]python cgi html pdf

I am writing a python CGI script that parses a csv file line by line and creates a HTML table using jinja2. 我正在编写一个Python CGI脚本,该脚本逐行解析csv文件并使用jinja2创建HTML表。 Ideally, each individual HTML instance (one for each line) will get saved as a PDF report. 理想情况下,每个单独的HTML实例(每行一个)将保存为PDF报告。

I've done a lot of searching, and I haven't been able to find a good way to go from HTML to PDF using python. 我已经进行了很多搜索,但还没有找到使用python从HTML转换为PDF的好方法。 Is it possible to render CGI to PDF? 是否可以将CGI渲染为PDF? What methods would you recommend to accomplish this task? 您会建议采用什么方法来完成此任务?

If you've done a lot of searching then I am sure you have seen all of the really complicated options for converting html to pdf: ReportLab, weasyprint, pdfkit, etc: as catalogued in this post: How to convert webpage into pdf using Python . 如果您已经进行了大量搜索,那么我相信您已经看到了将html转换为pdf的所有非常复杂的选项:ReportLab,weasyprint,pdfkit等:如本文中所述: 如何使用Python将网页转换为pdf

However, I literally just spent the last month working on the Jinja2 -> HTML -> PDF workflow, so hopefully something of my solution can help you. 但是,我实际上只是在上个月度过了Jinja2-> HTML-> PDF工作流程,所以希望我的解决方案可以为您提供帮助。 I found downloading wkhtmltopdf (a small command line program written in C - it's pretty great) and using it from subprocess be by far the easiest way to accomplish this task. 我发现下载wkhtmltopdf(一个用C编写的小型命令行程序-很好), 到目前为止 ,从subprocess进程中使用它是完成此任务的最简单方法。 My sample below: 我的样本如下:

import os
import jinja2
import subprocess

def render(template_path, context):
    # Context = jinja context dictionary 
    path, filename = os.path.split(template_path)
    return jinja2.Environment(loader=jinja2.FileSystemLoader(path or './')
                             ).get_template(filename
                                           ).render(context)

def create_pdf(custom_data, template_path, out_dir, context, keep_html=False):
    # Custom data = the part of my workflow that won't matter to you
    report_name = os.path.join(out_dir, custom_data + "_report")
    html_name = report_name + ".html"
    pdf_name = report_name + ".pdf"

    def write_html():
        with open(html_name, 'w') as f:
            html = render(template_path, context)
            f.write(html)
    write_html()

    args = '"C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf.exe" --zoom 0.75 -B 0 -L 0 -R 0 -T 0 {} {}'.format(html_name, pdf_name)
    child = subprocess.Popen(args, shell=True, stdout=subprocess.PIPE)
    # Wait for the sub-process to terminate (communicate) then find out the
    # status code
    output, errors = child.communicate()
    if child.returncode or errors:
        # Change this to a log message
        print "ERROR: PDF conversion failed. Subprocess exit status {}".format(
        child.returncode)
    if not keep_html:
        # Try block only to avoid raising an error if you've already moved
        # or deleted the html
        try:
            os.remove(html_name)
        except OSError:
            pass

Most of this code is well-explained by the documentation for jinja2 and subprocess so I won't laboriously go over it here. jinja2subprocess的文档对大多数代码进行了很好的解释,因此在这里我不会费力地进行介绍。 The arg flags in wkhtmltopdf translate to Zoom = 75% and 0 width margins (the -B, -L, etc are short hand for bottom, left, etc). wkhtmltopdf中的arg标志转换为Zoom = 75%和0的宽度边距(-B,-L等是底部,左侧等的简写)。 The wkhtmltopdf documention is also quite good. wkhtmltopdf文档也很好。

Edited: Credit for the render function goes to Matthias Eisen . 编辑: render功能归功于Matthias Eisen Usage: 用法:

Assuming a template at /some/path/my_tpl.html, containing: 假设模板位于/some/path/my_tpl.html,其中包含:

Hello {{ firstname }} {{ lastname }}! {{firstname}} {{lastname}},您好!

context = {
    'firstname': 'John',
    'lastname': 'Doe'
}
result = render('/some/path/my_tpl.html', context)

print(result)

Hello John Doe! 你好约翰·多伊!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM