生成多页PDF而不复制每页上的模板?

时间:2013-12-13 22:50:24

标签: python pdf ghostscript

我正在开发一个生成多页(有时数百或数千页)PDF文档进行打印的应用程序。每个页面都包含一个通用模板,其中叠加了一些特定于页面的内容(想想:自动填写纸质表单的“名称”字段)。

问题是,模板相当大(大约100kb /页),并且在每个页面上复制它会产生非常大型PDF文件(目前使用{{{ 1}}将一个充满SVG文件的目录转换为PDF格式。

是否可以通过引用静态模板来减少重复,以便每个PDF页面只包含自定义内容?

理想情况下,我想知道如何使用Python或Ghostscript执行此操作,但任何起点都会受到赞赏。

1 个答案:

答案 0 :(得分:1)

您想要的是PDF文件中的Form XObjects。来自 PDF参考:

  

表单XObject是一个独立的PDF内容流   任何图形对象序列的描述(包括路径   对象,文本对象和采样图像)。表单XObject可能是   多次绘制 - 在多个页面上或在多个位置绘制   在同一页面上 - 每次都产生相同的结果,仅限主题   在调用它时的图形状态。这不仅仅是这个   共享定义经济,在PDF文件中表示,但在   适合PDF用户应用程序可以优化的情况   通过缓存渲染表单XObject的结果来执行   重复使用。

许多应用程序添加例如水印到PDF页面,自动将它们添加为Form XObjects。例如,您可以使用pdftk将模板内容添加为已有页面特定内容的现有多页PDF的背景:

pdftk multipage.pdf background template.pdf output multipage+.pdf

使用Ghostscript,您应该将模板设置为EPS,然后创建添加了Form XObjects的多页PDF,然后使用其他一些方法添加特定于页面的内容。但是,也许可以使用"仅限Ghostscript" 来实现智能的东西,以便将特定页面强制执行到背景PDF。创造"准备填补"在每个页面上将PDF格式设为Form XObject,请执行以下操作:

gs -sDEVICE=pdfwrite -o 100_pages_template.pdf \
-c '[/_objdef {background} /BBox [0 0 595 841] /BP pdfmark 
save /showpage {} def 
0 0 translate       % adjust according to EPS BBox 
(template.eps) run 
restore 
[/EP pdfmark 
1 1 100 { 
  [{background} /SP pdfmark 
  showpage 
} for'

不了解Python,我认为它与使用Perl的下一个示例一样简单。在这里,我也在每页上创建了带有模板的100页PDF:

use strict;
use warnings;
use PDF::API2;

my $pdf = PDF::API2->new();
my $tmpl = PDF::API2->open('template.pdf');
my $xo = $pdf->importPageIntoForm($tmpl, 1);
for (1..100) {
    my $page = $pdf->page();
    my $gfx = $page->gfx();
    $gfx->formimage($xo, 0, 0);

   # add page specific content

}
$pdf->saveas('out.pdf');