Я пытаюсь создать многостраничный PDF-документ в iText с заполненными формами, по одному для каждого человека. Я просмотрел примеры того, как это сделать в Интернете, и использовал эти примеры в своем решении.iText Как создать многостраничный документ из заполняемого шаблона
PDF-шаблон является одним из созданных с помощью Adobe Acrobat Pro.
Я смог успешно заполнить и вернуть одностраничный документ PDF из своего шаблона с помощью iText, но процесс с несколькими документами, похоже, не работает правильно.
Это моя программа, которая показывает, что я пытаюсь сделать:
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfSmartCopy;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.NumberFormat;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
public class ITextTest
{
public static final String TEMPLATE =
"C:\\RAD7_5\\iTextTest\\iTextTest\\input\\LS213_1.pdf";
public static void main(String[] args)
{
ITextTest iTextTest = new ITextTest();
iTextTest.doItextTest();
}
public void doItextTest()
{
try
{
PdfReader pdfReader;
PdfStamper pdfStamper;
ByteArrayOutputStream baos;
Document document = new Document();
PdfSmartCopy pdfSmartCopy = new PdfSmartCopy(document,
new FileOutputStream("C:\\RAD7_5\\iTextTest\\iTextTest\\output\\LS213_1MultiTest.pdf"));
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
Date currDate = new Date();
NumberFormat numberFormat = NumberFormat.getCurrencyInstance();
double amount = 4127.29d;
document.open();
for(int i = 1; i <= 5; i++)
{
pdfReader = new PdfReader(TEMPLATE);
baos = new ByteArrayOutputStream();
pdfStamper = new PdfStamper(pdfReader, baos);
AcroFields acroFields = pdfStamper.getAcroFields();
//key statement 1
acroFields.setGenerateAppearances(true);
//acroFields.setExtraMargin(5, 5);
acroFields.setField("Name and Address", "John Doe\n123 Anywhere St.\nAnytown, USA 12345");
acroFields.setField("Case Number", "123456789");
acroFields.setField("Employer", "Employer Co., Inc.\n456 Anyhow ln.\nAnyville, USA 67890");
acroFields.setField("Date", dateFormat.format(currDate));
acroFields.setField("Name", "John Doe");
acroFields.setField("restitution check No", "65432" + i);
acroFields.setField("in the sum of", numberFormat.format(amount));
//key statement 2
pdfStamper.setFormFlattening(false);
pdfStamper.close();
pdfReader.close();
pdfReader = new PdfReader(baos.toByteArray());
pdfSmartCopy.addPage(pdfSmartCopy.getImportedPage(pdfReader, 1));
pdfSmartCopy.freeReader(pdfReader);
pdfReader.close();
}
document.close();
}
catch(DocumentException dex)
{
dex.printStackTrace();
System.exit(1);
}
catch(IOException ex)
{
ex.printStackTrace();
System.exit(1);
}
}
}
В приведенном выше коде, вы можете увидеть два ключевых заявления, которые влияют на результат заполненного шаблона:
acroFields.setGenerateAppearances(true);
pdfStamper.setFormFlattening(false);
С помощью вышеуказанных двух утверждений, если я устанавливаю первый в true, а второй - в false, он заполняет поля, но они смещены с метками. Кроме того, после первой копии шаблона каждая копия после этого имеет некоторые незаполненные поля по какой-либо причине.
Если установить их как истину:
acroFields.setGenerateAppearances(true);
pdfStamper.setFormFlattening(true);
он устанавливает все поля во всех копиях шаблона. Это самый успешный результат для меня до сих пор, но заполненные поля по-прежнему не совпадают с метками, а выравнивание формы до истины больше не позволяет пользователю вручную корректировать поле вручную, если данные в приложении неверны.
Если установить первый в ложь, а второй к истинным:
acroFields.setGenerateAppearances(false);
pdfStamper.setFormFlattening(true);
все поля полностью пустой (худший результат).
Если установить их как ложь:
acroFields.setGenerateAppearances(false);
pdfStamper.setFormFlattening(false);
то поля заполняются и появляются в правильном выравнивании с этикетками. Но по каким-либо причинам поля будут пустыми, пока вы не нажмете на них. И проблема с некоторыми полями, которые были уничтожены на последующих страницах, происходит, как в истинном ложном сценарии (упомянутый первый сценарий).
Мне интересно, возможно ли, чтобы это работало без неправильных значений поля, без выравнивания полей и без потерянных полей на последующих страницах.
Я знаю, что вы можете настроить поля после использования
acroFields.setExtraMargin(extraMarginLeft, extraMarginTop)
, но с использованием
acroFields.setGenerateAppearances(false)
работает отлично для одной формы без изменения полей и я хочу работать для многостраничных документ также.
Кроме того, с помощью
acroFields.setGenerateAppearances(true)
приводит текст двигаться и смещаться немного в текстовом поле при нажатии на нее. Это происходит как для одностраничных документов, так и для многостраничных документов. Кажется, что в iText или PDF-шаблонах, созданных с помощью Adobe Pro, появляется ошибка при настройке полей с помощью setGenerateAppearances (true).
В настоящее время я использую iText 5.5.8.
Любая помощь с этой проблемой была бы весьма признательна. Спасибо, что нашли время, чтобы прочитать это.
Первая ссылка, которую вы предоставили («Как объединить формы из разных файлов в один PDF?»), Решила проблему с полями на последующих страницах, которые были уничтожены. Переименование полей работало для сохранения интерактивности пользователя. И ваше объяснение setGenerateAppearances() решило проблему с несогласованными полями. Если мы закончим использование нескольких просмотрщиков PDF (зрителей, отличных от Adobe Reader), я верну его значение true и с помощью операторов setExtraMargin() настройте выравнивание. Ваш ответ был очень полезным, и теперь наши документы работают должным образом. Спасибо за вашу помощь. –