13

我经常从我们的设计师(内置于 Adob​​e InDesign)那里得到一个 PDF,它应该发送给成千上万的人。

我有所有人的名单,在 OpenOffice.org 中进行邮件合并很容易。但是,OpenOffice.org 不支持高级 PDF。我只想在每一页上输出一些文本并打印出来。

我现在是这样做的:打印出 6.000 份 PDF,然后将它们全部重新放入打印机,然后在上面打印出姓名、地址和其他信息。但这很昂贵。

可悲的是,我无法将 PDF 制作成图像并在 OpenOffice.org 中使用它,因为它会使计算机停止运行。将此作业发送到打印机也需要很长时间。

那么,有没有一种简单的方法可以在不支付第三方封闭解决方案的情况下进行这种邮件合并(最好在 Python 中)?

4

11 回答 11

7

现在我已经开户了。我使用巧妙的 pdftk 修复了它。

在我的任务中,我完全忽略了“背景”和“叠加”功能。我的解决方案是这样的:

pdftk names.pdf background boat_background.pdf output out.pdf

使用 Python reportlab 或类似的 PDF创建names.pdf脚本可以轻松创建。最好使用代码来做到这一点,在 LibreOffice/OpenOffice 中创建 6k 页面需要几个小时,而使用 Python 只需要几秒钟。

于 2009-09-28T01:32:11.853 回答
2

有两种更简单、更便宜的解决方案。

首先,您可以使用 DataMerge 在 InDesign 中直接进行邮件合并。这是在 CS 中添加到 InDesign 的实用程序。您以 CSV 格式导出或保存您的姓名。将数据导入 InDesign 模板,然后将您的姓名、地址和布局中的此类字段放入其中。按开始。它将创建一个包含所有已完成字母的新文档,或者您可以直接进入打印机。

或者,您可以将数据导出到 XML 文件并在 InDesign 中使用 XML 占位符创建动态布局。

Adobe InDesign 和 XML 设计师指南一书将教您如何做到这一点,或者您可以查看 Lynda.com 视频,了解 InDesign 和 XML 的动态工作流程。

很容易做到。

如果您想为邮件合并创建单独的 PDF 文件,您可以用一个文件中的所有名称运行一个长 PDF,然后在 Acrobat Pro 本身中执行提取以分离 PDF 文件。

于 2012-07-05T23:34:57.963 回答
2

您可能会查看像iText这样的 PDF 库。如果您有一些编程知识和一点时间,您可以编写一些代码,将联系信息添加到 PDF

于 2008-12-10T15:48:19.603 回答
1

对于一个没有混乱,没有大惊小怪的解决方案,使用 iText 将文本简单地添加到 pdf 中。例如,您可以执行以下操作以在加载后将文本添加到 pdf 文档:

PdfContentByte cb= ...;
cb.BeginText();
cb.SetFontAndSize(font, fontSize);
float x = ...;
float y = ...;
cb.SetTextMatrix(x, y);
cb.ShowText(fieldValue);
cb.EndText();    

从那里开始,将其另存为不同的文件,然后打印。

但是,我发现表单字段是从模板生成 pdf 文档的方法。

如果您有一个带有表单域的模板(使用 Adob​​e Acrobat 添加),您有以下两种选择之一:

  • 创建一个 FDF 文件,它本质上是表单上字段的值列表。FDF 是一个简单的文本文档,它引用原始文档,因此当您打开 PDF 时,文档会加载 FDF 提供的字段值。
  • 或者,使用 iText / iTextSharp 之类的库加载模板,手动填写表单字段,然后将其保存为单独的 pdf。

示例 FDF 文件如下所示(从Planet PDF窃取):

%FDF-1.2
%âãÏÓ
1 0 obj
<<<
 /F(Example PDF Form.pdf)
 /Fields[
  <<
  /T(myTextField)
  /V(myTextField default value)
  >>
  ]
 >>
>> endobj trailer
<>
%%EOF

由于 FDF 的简单格式和小尺寸,这是首选方法,并且该方法应该适用于任何语言。

至于以编程方式填充字段,您可以通过以下方式使用 iText:

PdfAcroForm acroForm = writer.AcroForm;
acroForm.Put(new PdfName(fieldInfo.Name), new PdfString(fieldInfo.Value));
于 2008-12-10T17:17:54.103 回答
1

如果您无法以 PDF 以外的其他格式获取模板,则一个简单的临时解决方案是

  • 将 PDF 转换为图像
  • 将图像放在 (OpenOffice.org) 文档的背景中
  • 将邮件合并字段放在图像顶部
  • 做邮件合并和打印
于 2008-12-10T15:49:34.123 回答
1

可能最好的方法是生成另一个带有缺失文本的 PDF,并将一个 PDF 覆盖在另一个上。快速谷歌发现这个链接显示如何在 Acrobat 中执行此操作,我相信还有其他方法。

http://forums.macrumors.com/showthread.php?t=508226

于 2008-12-10T16:36:51.110 回答
1

如何使用可变数据程序,例如 Adob​​e Indesign 的 XMPie。这是一个应该引用您的人员列表的插件(尽管认为它可能必须是 Excel 中的列表)。

于 2011-12-17T21:15:30.370 回答
1

有人询问具体情况。我不想用它来玷污我的最佳答案,因为您可以按照自己的喜好进行操作(只要知道 pdftk 由它决定就应该给人们这个想法)。

但这是我多年前使用的一些脚本:

csv_to_pdf.py

#!/usr/bin/python
# This makes one PDF page per name in the CSV file
# csv_to_pdf.py <CSV_FILE>

import csv
import sys
from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.units import cm, mm

in_db = csv.reader(open(sys.argv[1], "rb"));
outname = sys.argv[1].replace("csv", "pdf")
pdf = Canvas(outname)
in_db.next()

i = 0
for rad in in_db:
        pdf.setFontSize(11)
        adr = rad[1]

        tekst = pdf.beginText(2*cm, 26*cm)

        for a in adr.split('\n'):
            if not a.strip():
                continue
            if a[-1] == ',':
                a = a[:-1]
            tekst.textLine(a)
        pdf.drawText(tekst)
        pdf.showPage()

        i += 1
        if i % 1000 == 0:
                print i
pdf.save()

运行此程序后,您将拥有一个包含数千页的文件,其中只有一个名称。这是您可以在所有这些下放置精美 PDF 的背景:

pdftk <YOUR_NEW_PDF_FILE.pdf> background <DESIGNED_FILE.pdf> <MERGED.pdf>
于 2019-07-31T16:53:47.357 回答
1

一种简单的方法是从 Acrobat 中的原始文档创建一个可填写的 pdf 表单,并与表单和 csv 进行邮件合并。

PDF 邮件合并在 python 和pdftk中相对容易。Fdfgen ( pip install fdfgen) 是一个 python 库,它将从 python 数组创建 fdf,因此您可以将 excel 网格保存到 csv,确保 csv 标题与您要填充该列的 pdf 表单字段的名称匹配,并做类似的事情

import csv
import subprocess

from fdfgen import forge_fdf

PDF_FORM = 'path/to/form.pdf'
CSV_DATA = 'path/to/data.csv'

infile = open(CSV_DATA, 'rb')
reader = csv.DictReader(infile)
rows = [row for row in reader]
infile.close()

for row in rows:
    # Create fdf
    filename = row['filename'] # Construct filename
    fdf_data = [(k,v) for k, v in row.items()]
    fdf = forge_fdf(fdf_data_strings=fdf_data)
    fdf_file = open(filename+'.fdf', 'wb')
    fdf_file.write(fdf)
    fdf_file.close()

    # Use PDFTK to create filled, flattened, pdf file
    cmds = ['pdftk', PDF_FORM, 'fill_form', filename+'.fdf',
            'output', filename+'.pdf', 'flatten', 'dont_ask']
    process = subprocess.Popen(cmds, stdout=subprocess.PIPE)
    stdout, stderr = process.communicate()
    returncode = process.poll()
    os.remove(filename+'.fdf')

我已经遇到了足够多的问题来编写我自己的免费解决方案PdfZero。PdfZero 具有邮件合并功能,可将电子表格与 PDF 表单合并。您仍然需要创建一个 PDF 表单,但您可以将表单和 csv 上传到 pdfzero,选择要填充哪些列的表单字段,如果需要,使用 csv 数据为每个填充的 pdf 创建命名约定,然后批量生成填充的 PDfs。

免责声明:我写了 PdfZero

于 2019-07-19T15:28:24.923 回答
0

您可以使用 InDesign 的数据合并功能,或者您可以执行您一直在做的事情,打印一部分作业,然后使用 Word 或 Open Office 在其上打印邮件合并。但也要考虑寻找一家可以进行可变数据胶印或动态出版的公司。前期可能会贵一点,但在时间、测试、甚至包装和邮寄方面可以节省一大笔钱。

于 2015-05-18T05:34:11.500 回答
0

免责声明:我是这个工具的作者。

我遇到这个问题的次数足够多,为此我构建了一个免费的在线工具:https ://pdfbatchfill.com/

它假定 PDF 表单作为模板,并将其与 CSV 表单数据一起使用以生成单个 PDF 或 zip 文件中的单个 PDF。

于 2017-01-25T00:10:37.357 回答