使用Python和HTMLDOC动态地将html转换为pdf

2024-09-25 04:26:39 发布

您现在位置:Python中文网/ 问答频道 /正文

大约一年前,我为一个客户机构建了一个Django应用程序。他现在已经把申请转售给了一些超级机密的政府机构,他们甚至不告诉我他的名字。在

应用程序的一部分使用python库xhtml2pdf(pisa)动态生成PDF文件。政府不喜欢这个图书馆,他们不会告诉我为什么,他们说我必须使用HTMLDOC来生成pdf。在

关于这个库的文档不多,但是从阅读PHP示例来看,您可以通过shell与它通信,因此它应该可以与Python一起工作。但是,我很难将html传递给HTMLDOC。看起来HTMLDOC只接受一个文件,但我确实需要将html作为字符串传递,因为它是动态生成的。(或者将html字符串写入临时文件,然后将该临时文件传递给HTMLDOC)。在

我以为StringIO可以解决这个问题,但我得到了一个错误。以下是我所拥有的:

def render_to_pdf(template_src, context_dict):
    template = get_template(template_src)
    context = Context(context_dict)
    html  = template.render(context)
    result = StringIO.StringIO(html.encode("utf-8"))
    os.putenv("HTMLDOC_NOCGI", "1")

    #this line throws "[Errno 2] No such file or directory"
    htmldoc = subprocess.Popen("htmldoc -t pdf --quiet '%s'" % result, stdout=subprocess.PIPE).communicate()

    pdf = htmldoc[0]
    result.close()
    return HttpResponse(pdf, mimetype='application/pdf')

任何想法、建议或帮助都将不胜感激。在

谢谢。在

更新

堆栈跟踪:

^{pr2}$

Tags: 文件字符串src应用程序pdfhtmlcontext动态
2条回答

布莱格。多么可怕的要求,一个可怕的计划。在

似乎没有任何方法可以将要转换的内容作为命令行选项。不过,它似乎确实接受了一个URL。因此,可以想象,您可以传递一个构造的URL,该URL引用同一服务器上的视图,然后在第二个视图中输出呈现的模板,然后由从第一个视图运行的HTMLDOC获取该模板。请注意,这将不适用于开发服务器,因为它是单线程的,因此视图将永远相互等待。在

首先,subprocess.Popen的第一个参数通常应该是一个列表(除非您还传递了shell=True)。No such file or directory几乎可以肯定是由于系统中缺少名为"htmldoc -t pdf quiet '...的文件(它试图查找并运行为整个字符串值命名的程序)。在

其次,如果你在htmldoc的stdin上给htmldoc一些html,它就会在stdout上输出一个pdf文件,从而避免了对临时文件的需要。在

尝试一下(未经测试):

htmldoc = subprocess.Popen(
  ['/usr/bin/htmldoc', '-t', 'pdf', ' webpage', '-'], 
  stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
stdout, stderr = htmldoc.communicate(html)

注意:用/usr/bin/htmldoc代替系统上htmldoc的真正路径。在

htmldoc程序的-参数告诉它从stdin读取。您将把html字符串值(html)作为htmldoc.communicate调用的参数传递给htmldoc的stdin。生成的pdf输出应该在stdout中可用,任何其他消息或统计信息都应该在stderr中可用。在

编辑:文档看起来确实有点不可靠,但确实有很多。对于html in one page或{a2}版本,或者man page,您可能会有更好的运气。在

另外,一定要向htmldoc进程的stdin传递一个字符串或类似的字符串。直接传递StringIO对象,正如我前面的代码片段所暗示的那样,将不起作用。在

相关问题 更多 >