Как сделать слияние почты поверх PDF?

Я часто получаю PDF от нашего дизайнера (встроенного в Adobe InDesign), который должен быть разослан тысячам людей.

У меня есть список со всеми людьми, и легко слить почту в OpenOffice.org. Однако OpenOffice.org не поддерживает расширенный PDF. Я просто хочу вывести текст на каждую страницу и распечатать его.

Вот как я это делаю сейчас: распечатайте 6.000 копий PDF, затем снова поместите все их в принтер и просто распечатайте имя, адрес и другую информацию поверх него. Но это дорого.

К сожалению, я не могу создать PDF-файл с изображением и использовать его в OpenOffice.org, потому что он останавливает работу компьютера. Отправка этой работы на принтер также занимает очень много времени.

Итак, есть ли простой способ сделать это слияние (желательно на Python) без оплаты сторонних закрытых решений?

10.12.2008 15:38:41
11 ОТВЕТОВ

Вы могли бы, вероятно, посмотреть на PDF-библиотеку, как iText . Если у вас есть знания в области программирования и немного времени, вы можете написать код, который добавляет контактную информацию в PDF-файлы.

2
10.12.2008 15:48:19

Если вы не можете получить шаблон в другом формате, чем PDF, простое специальное решение будет

  • преобразовать PDF в изображение
  • поместите изображение в фон вашего документа (OpenOffice.org)
  • расположение полей слияния в верхней части изображения
  • сделать слияние и печать почты
1
10.12.2008 15:49:34
Задание на печать становится ОГРОМНЫМ и никогда не закончится.
Velmont 20.03.2009 12:47:20
Что ж, тогда проще всего было бы попросить вашего дизайнера предоставить шаблон в жизнеспособном формате (или получить копию Adobe Acrobat Professional, я думаю, должна быть возможность использовать преобразование PDF в форму). Кажется, что окупаемость доставки 6000 писем должна оправдать такие инвестиции.
Dirk Vollmar 20.03.2009 15:27:31

Вероятно, лучшим способом было бы создать другой PDF-файл с отсутствующим текстом и наложить один PDF-файл поверх другого. Быстрый Google нашел эту ссылку, показывающую, как это сделать в Acrobat, и я уверен, что есть и другие методы.

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

1
10.12.2008 16:36:51

Для беспрепятственного, беспроблемного решения используйте 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-документов из шаблонов.

Если у вас есть шаблон с полями формы (добавлен в Adobe 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));
1
11.12.2008 04:44:03
Но можно ли поместить 6000 имен в один FDF или мне нужно создать 6000 файлов FDF, а затем вывести 6000 5MiB PDF-файлов (что будет ОГРОМНО и займет вечно)?
Velmont 20.03.2009 12:48:48

Теперь я сделал аккаунт. Я исправил это, используя оригинальный pdftk.

В своем квесте я полностью пропускаю функции «фон» и «наложение». Мое решение было таким:

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

Создание names.pdfвы можете легко сделать с помощью Python reportlab или аналогичных сценариев создания PDF. Для этого лучше всего использовать код, на создание 6k-страниц в LibreOffice / OpenOffice уходит несколько часов, а на Python - всего несколько секунд.

7
5.11.2018 12:57:36
Я голосую, потому что это решение другой моей проблемы, не связанной с формами, а скорее «печатью» текста в pdf
Douglas Anderson 25.02.2011 11:25:56
Ссылка не работает.
stoic 5.11.2018 09:40:15
Спасибо @stoic, удалив ссылку, потому что она в основном просто детализирует все неудачные попытки, которые у меня были, и почему они потерпели неудачу (ну, некоторые почти работали). Я думаю, что я также написал и показал скрипт для создания names.pdfфайла, но вы можете легко сделать это с помощью Python. Сначала я попробовал LibreOffice, но это заняло 4+ часа, Python занял 4 секунды.
odinho - Velmont 5.11.2018 12:56:12
Можете ли вы привести примеры names.pdfи boat_background.pdf? Это кажется отличным решением, но у меня возникли проблемы с выяснением специфики. Я думаю, что примеры обоих файлов помогут.
MikeyE 18.04.2019 01:17:06
Привет @MikeyE - мой сайт имел примеры, но я не настроил его снова. Я действительно добавил базовый сценарий, который я написал в другом ответе сейчас: stackoverflow.com/a/57295681/179978
odinho - Velmont 31.07.2019 16:55:04

Как насчет использования программы с переменными данными, такой как - XMPie для Adobe Indesign. Это плагин, который должен ссылаться на ваш список людей (хотя это может быть список в Excel).

1
17.12.2011 21:15:30

Есть два гораздо более простых и дешевых решения.

Во-первых, вы можете выполнить слияние писем непосредственно в InDesign, используя DataMerge. Это утилита, добавленная в InDesign еще в CS. Вы экспортируете или сохраняете свои имена в формате CSV. Импортируйте данные в шаблон InDesign, а затем вставьте свое имя, адрес и такие поля в макет. Нажмите Go. Он создаст новый документ со всеми готовыми буквами, или вы можете перейти прямо к принтеру.

ИЛИ, вы можете экспортировать свои данные в файл XML и создать динамический макет, используя заполнители XML в InDesign.

В книге «Руководство дизайнера по Adobe InDesign и XML» вы узнаете, как это сделать, или вы можете посмотреть видеоролики Lynda.com о динамических рабочих процессах с InDesign и XML.

Очень легко сделать.

Если вы хотите создать отдельные файлы PDF для слияния, вы можете запустить один длинный PDF со всеми именами в одном файле, а затем выполнить Извлечение в отдельные файлы PDF в самом Acrobat Pro.

2
5.07.2012 23:34:57
Более дешевый? По крайней мере, не так, как по стоимости, потому что pdftk бесплатен. Это также очень быстро. В конце концов, я использовал reportlab pdfgen plus pdftk для этой работы. И от того, что раньше ушли часы, теперь требуется всего несколько секунд, чтобы объединить 50-страничный CSV-файл поверх PDF-файла. :-)
odinho - Velmont 11.03.2013 15:21:27

Вы можете использовать функцию слияния данных InDesign или сделать то, что вы делали, распечатав часть работы, а затем распечатать слияние почты поверх этого с помощью Word или Open Office. Но также обратите внимание на поиск компании, которая может заниматься офсетной печатью переменных данных или динамической публикацией. Может быть немного дороже, но может сэкономить пакет, когда дело доходит до времени, тестирования, даже упаковки и рассылки.

0
18.05.2015 05:34:11

Отказ от ответственности : я автор этого инструмента.

Я сталкивался с этой проблемой достаточно много раз, чтобы создать для нее бесплатный онлайн-инструмент: https://pdfbatchfill.com/

Он принимает форму PDF в качестве шаблона и использует ее вместе с данными формы CSV для создания одного PDF или отдельных PDF-файлов в ZIP-файле.

0
25.01.2017 00:10:37

Одним простым способом было бы создать заполняемую PDF-форму из исходного документа в Acrobat и выполнить слияние почты с формой и CSV-файлом.

PDF-слияния относительно легко сделать в python и pdftk . Fdfgen ( pip install fdfgen) - это библиотека Python, которая создаст fdf из массива python, поэтому вы можете сохранить сетку 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, выбрать поля формы, которые вы хотите заполнить какими столбцами, создать соглашение об именах для каждого заполненного pdf, используя данные CSV, если это необходимо, и выполнить пакетную генерацию. заполненные PDF.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я написал PdfZero

1
19.07.2019 15:28:24

Кто-то попросил конкретику. Я не хотел запачкать свой главный ответ этим, потому что вы можете делать это как хотите (и просто зная, что 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>
1
31.07.2019 16:53:47