IText объединяет документы с акрополями
В настоящее время у меня есть PdfReader и PdfStamper, которыми я заполняю поля. Теперь мне нужно скопировать другой PDF-файл в конец той формы, которую я заполнял, и когда я это сделаю, я теряю акрополь новой формы, которую я копирую. Вот код
public static void addSectionThirteenPdf(PdfStamper stamper, Rectangle pageSize, int pageIndex){
PdfReader reader = new PdfReader(FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/resources/documents/Section13.pdf"));
AcroFields fields = reader.getAcroFields();
fields.renameField("SecurityGuidancePage3", "SecurityGuidancePage" + pageIndex);
stamper.insertPage(pageIndex, pageSize);
stamper.replacePage(reader, 1, pageIndex);
}
То, как я создаю оригинальный документ, выглядит следующим образом.
OutputStream output = FacesContext.getCurrentInstance().getExternalContext().getResponseOutputStream();
PdfReader pdfTemplate = new PdfReader(FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/resources/documents/dd254.pdf"));
PdfStamper stamper = new PdfStamper(pdfTemplate, output);
stamper.setFormFlattening(true);
AcroFields fields = stamper.getAcroFields();
Есть ли способ слияния с использованием первой части кода и слияния обоих акрополей вместе?
1 ответ
В зависимости от того, что именно вы хотите, возможны разные сценарии, но в любом случае: вы делаете это неправильно. Вы должны использовать либо PdfCopy
или же PdfSmartCopy
объединить документы.
Различные сценарии описаны в следующем видеоуроке.
Вы можете найти большинство примеров в песочнице iText.
Объединение разных форм (с разными полями)
Если вы хотите объединить различные формы без их выравнивания, вы должны использовать PdfCopy
как это делается в примере MergeForms:
public void createPdf(String filename, PdfReader[] readers) throws IOException, DocumentException {
Document document = new Document();
PdfCopy copy = new PdfCopy(document, new FileOutputStream(filename));
copy.setMergeFields();
document.open();
for (PdfReader reader : readers) {
copy.addDocument(reader);
}
document.close();
for (PdfReader reader : readers) {
reader.close();
}
}
В этом случае, readers
это массив PdfReader
экземпляры, содержащие разные формы (с разными именами полей), поэтому мы используем PdfCopy
и мы уверены, что мы не забываем использовать setMergeFields()
метод, иначе поля не будут скопированы.
Объединение одинаковых форм (с одинаковыми полями)
В этом случае нам нужно переименовать поля, потому что мы, вероятно, хотим разные значения на разных страницах. В PDF поле может иметь только одно значение. Если вы объединяете идентичные формы, у вас есть несколько визуализаций одного и того же поля, но каждая визуализация будет показывать одно и то же значение (потому что в действительности есть только одно поле).
Давайте посмотрим на пример MergeForms2:
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
Document document = new Document();
PdfCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest));
copy.setMergeFields();
document.open();
List<PdfReader> readers = new ArrayList<PdfReader>();
for (int i = 0; i < 3; ) {
PdfReader reader = new PdfReader(renameFields(src, ++i));
readers.add(reader);
copy.addDocument(reader);
}
document.close();
for (PdfReader reader : readers) {
reader.close();
}
}
public byte[] renameFields(String src, int i) throws IOException, DocumentException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, baos);
AcroFields form = stamper.getAcroFields();
Set<String> keys = new HashSet<String>(form.getFields().keySet());
for (String key : keys) {
form.renameField(key, String.format("%s_%d", key, i));
}
stamper.close();
reader.close();
return baos.toByteArray();
}
Как видите, renameFields()
Метод создает новый документ в памяти. Этот документ объединяется с другими документами, используя PdfSmartCopy
, Если бы вы использовали PdfCopy
здесь ваш документ будет раздут (как мы скоро узнаем).
Слияние сплющенных форм
В FillFlattenMerge1 мы заполняем формы, используя PdfStamper
, Результатом является файл PDF, который хранится в памяти и объединяется с использованием PdfCopy
, Хотя этот пример подходит для объединения разных форм, на самом деле это пример того, как этого не делать (как объяснено в видеоуроке).
FillFlattenMerge2 показывает, как объединить идентичные формы, которые правильно заполнены и сведены:
public void manipulatePdf(String src, String dest) throws DocumentException, IOException {
Document document = new Document();
PdfCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest));
document.open();
ByteArrayOutputStream baos;
PdfReader reader;
PdfStamper stamper;
AcroFields fields;
StringTokenizer tokenizer;
BufferedReader br = new BufferedReader(new FileReader(DATA));
String line = br.readLine();
while ((line = br.readLine()) != null) {
// create a PDF in memory
baos = new ByteArrayOutputStream();
reader = new PdfReader(SRC);
stamper = new PdfStamper(reader, baos);
fields = stamper.getAcroFields();
tokenizer = new StringTokenizer(line, ";");
fields.setField("name", tokenizer.nextToken());
fields.setField("abbr", tokenizer.nextToken());
fields.setField("capital", tokenizer.nextToken());
fields.setField("city", tokenizer.nextToken());
fields.setField("population", tokenizer.nextToken());
fields.setField("surface", tokenizer.nextToken());
fields.setField("timezone1", tokenizer.nextToken());
fields.setField("timezone2", tokenizer.nextToken());
fields.setField("dst", tokenizer.nextToken());
stamper.setFormFlattening(true);
stamper.close();
reader.close();
// add the PDF to PdfCopy
reader = new PdfReader(baos.toByteArray());
copy.addDocument(reader);
reader.close();
}
br.close();
document.close();
}
Это три сценария. Ваш вопрос слишком неясен для всех, кроме вас, чтобы решить, какой сценарий лучше всего подходит для ваших нужд. Я предлагаю вам потратить время на изучение, прежде чем писать код. Посмотрите видео, попробуйте примеры, и если у вас все еще есть сомнения, вы сможете опубликовать более умный вопрос.