如何在App Engine上的后台任务中逐页生成pdf文档

时间:2012-04-22 12:22:32

标签: python google-app-engine reportlab

我需要生成100多页的PDF文档。这个过程需要处理大量数据,而且一次性生成需要更多的时间和内存。

我尝试了一些不同的方法来破解我的方式:

随着结果的不同,我得到了它的工作,但它很慢并且需要更多的内存(有时会达到实例软内存限制)。目前,我在不同的任务中生成一些部分,将每个部分存储在blobstore中,然后将它们与pyPdf合并,但它会在较大的文档上窒息。

我正在生成的文档并不复杂,主要是表格和文本,没有内部引用,没有TOC,没有任何应该知道文档其余部分的内容。我可以使用platypus进行布局,我不需要花哨的文档外观或HTML2PDF转换。

目标是以数据存储允许的速度生成文档。并行页面生成会很好,但不是必需的。

我在考虑使用blobstore files api逐页生成,其中每个任务都会生成一个页面,最后一个任务将最终确定blobstore文件,使其可读。但我似乎无法找到如何,暂停生成,将部分PDF存储到流中,然后使用该流恢复生成以生成不同任务中的下一页。

所以我的问题是:

如何在GAE上生成大于几页的PDF文档,在任务请求之间拆分生成,然后将生成的文档存储在blobstore中?

如果使用reportlab无法进行生成拆分,那么如何最小化合并不同PDF文档的占用空间,使其符合GAE任务请求设置的限制?

更新 转换API的替代品非常受欢迎。

第二次更新 转换API正在退役,因此现在不是一个选项。

第三次更新 可以在这里使用Pileline或MapReduce API吗?

2 个答案:

答案 0 :(得分:1)

答案 1 :(得分:1)

我建议在应用引擎上安装wkhtmltopdf。 Wkhtmltopdf是一个命令行工具,用于将html呈现为pdf。

创建html文件,然后使用wkhtmltopdf将它们逐个转换为pdf。

在Windows上你可以使用(在基于linux的系统下,它有类似的东西):

def create_pdf(in_html_file=None, out_pdf_file=None, quality=None):
    pathtowk = 'C:/wkhtmltopdf/bin/wkhtmltopdf.exe {0} {1} {2}'    

    if quality == 1: # super quality no compression
        args_str = '--encoding utf-8 --disable-smart-shrinking --no-pdf-compression --page-size A4 --zoom 1 -q -T 15.24mm -L 25.4mm -B 20.32mm  -R 33.02mm'
    elif quality == 2: # moderate quality some compression
        args_str = '--encoding utf-8 --disable-smart-shrinking --page-size A4 --zoom 1 -q -T 15.24mm -L 25.4mm -B 20.32mm  -R 33.02mm'
    else: # poor quality max compression
        args_str = '--encoding utf-8 --page-size A4 --zoom 1 -q -T 15.24mm -L 25.4mm -B 20.32mm  -R 33.02mm'

    os.system(pathtowk.format(args_str, in_html_file, out_pdf_file))

或者您可以使用subprocess.call(pathtowk.format(args_str, in_html_file, out_pdf_file))执行wkhtmltopdf(我的意见更好)。

转换过程完成后,使用PyPdf2将生成的PDF合并为单个文件。