自动化PDF生成

3 投票
2 回答
3876 浏览
提问于 2025-04-17 07:47

有什么好的工具可以用来生成PDF报告吗?特别是我们想制作一些互动的PDF,里面可以嵌入视频,就像这个例子这里展示的那样。

目前我们使用Python和reportlab来生成PDF,但还没有完全探索这个库(主要是因为它的许可证费用有点高)。

我们也在看Adobe的SDKiText库,但很难判断它们各自的功能。

如果能从一个模板PDF生成文档,那就更好了。

任何建议或评论都非常感谢。

谢谢,

2 个回答

0

我建议使用 这个链接 来把HTML转换成PDF文件。

然后你可以用任何你喜欢的工具来把报告做成HTML格式。我个人喜欢 这个网站

5

最近,我需要为一个Django应用程序创建PDF报告。虽然有ReportLab的许可证,但我最后选择了LaTeX。这种方法的好处是,我们可以使用Django模板来生成LaTeX源代码,这样就不用为我们需要创建的多个报告写很多代码了。而且,LaTeX的语法相对简洁(虽然它也有很多独特之处,并不适合所有用途)。

这个代码片段提供了这种方法的一般概述。我发现有必要做一些修改,具体内容我在这个问题的最后提供了。主要的新增功能是检测Rerun LaTeX消息,这表示需要进行额外的处理。使用起来非常简单:

def my_view(request):
    pdf_stream = process_latex(
        'latex_template.tex',
        context=RequestContext(request, {'context_obj': context_obj})
    )
    return HttpResponse(pdf_stream, content_type='application/pdf')

在用LaTeX生成的PDF中嵌入视频是可能的,不过我没有这方面的经验。这里有一个很好的Google搜索结果

这个解决方案确实需要启动一个新进程(pdflatex),所以如果你想要一个纯Python的解决方案,那就继续寻找吧。

import os
from subprocess import Popen, PIPE
from tempfile import NamedTemporaryFile

from django.template import loader, Context


class LaTeXException(Exception):
    pass


def process_latex(template, context={}, type='pdf', outfile=None):
    """
    Processes a template as a LaTeX source file.
    Output is either being returned or stored in outfile.
    At the moment only pdf output is supported.
    """
    t = loader.get_template(template)
    c = Context(context)
    r = t.render(c)

    tex = NamedTemporaryFile()
    tex.write(r)
    tex.flush()
    base = tex.name
    names = dict((x, '%s.%s' % (base, x)) for x in (
        'log', 'aux', 'pdf', 'dvi', 'png'))
    output = names[type]

    stdout = None
    if type == 'pdf' or type == 'dvi':
        stdout = pdflatex(base, type)
    elif type == 'png':
        stdout = pdflatex(base, 'dvi')
        out, err = Popen(
            ['dvipng', '-bg', '-transparent', names['dvi'], '-o', names['png']],
            cwd=os.path.dirname(base), stdout=PIPE, stderr=PIPE
        ).communicate()

    os.remove(names['log'])
    os.remove(names['aux'])

    # pdflatex appears to ALWAYS return 1, never returning 0 on success, at
    # least on the version installed from the Ubuntu apt repository.
    # so instead of relying on the return code to determine if it failed,
    # check if it successfully created the pdf on disk.
    if not os.path.exists(output):
        details = '*** pdflatex output: ***\n%s\n*** LaTeX source: ***\n%s' % (
            stdout, r)
        raise LaTeXException(details)

    if not outfile:
        o = file(output).read()
        os.remove(output)
        return o
    else:
        os.rename(output, outfile)


def pdflatex(file, type='pdf'):
    out, err = Popen(
        ['pdflatex', '-interaction=nonstopmode', '-output-format', type, file],
        cwd=os.path.dirname(file), stdout=PIPE, stderr=PIPE
    ).communicate()

    # If the output tells us to rerun, do it by recursing over ourself.
    if 'Rerun LaTeX.' in out:
        return pdflatex(file, type)
    else:
        return out

撰写回答