我正在开发一个生成多页(有时数百或数千页)PDF文档进行打印的应用程序。每个页面都包含一个通用模板,其中叠加了一些特定于页面的内容(想想:自动填写纸质表单的“名称”字段)。
问题是,模板相当大(大约100kb /页),并且在每个页面上复制它会产生非常大型PDF文件(目前使用{{{ 1}}将一个充满SVG文件的目录转换为PDF格式。
是否可以通过引用静态模板来减少重复,以便每个PDF页面只包含自定义内容?
理想情况下,我想知道如何使用Python或Ghostscript执行此操作,但任何起点都会受到赞赏。
答案 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');