java - IText fusiona documentos con acrofields
adobe (1)
Actualmente tengo un PdfReader y un PdfStamper con el que estoy completando los campos. Ahora tengo que copiar otro pdf al final de ese formulario que he estado completando y cuando lo hago, pierdo el acrofield en el nuevo formulario que copio. Aquí está el código.
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);
}
La forma en que estoy creando el documento original es así.
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();
¿Hay alguna manera de fusionar usando la primera pieza de código y fusionar ambos acrofields juntos?
Dependiendo de lo que quiera exactamente, son posibles diferentes escenarios, pero en cualquier caso: lo está haciendo mal.
Debe usar
PdfCopy
o
PdfSmartCopy
para fusionar documentos.
Los diferentes escenarios se explican en el siguiente video tutorial .
Puede encontrar la mayoría de los ejemplos en el sandbox iText .
Fusionar diferentes formas (tener diferentes campos)
Si desea fusionar
diferentes
formularios sin aplanarlos, debe usar
PdfCopy
como se hace en el ejemplo de
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();
}
}
En este caso, los
readers
son una matriz de instancias de
PdfReader
contienen
diferentes
formas (con diferentes nombres de campo), por lo tanto, usamos
PdfCopy
y nos aseguramos de no olvidarnos de usar el método
setMergeFields()
, o los campos no serán copiado
Fusionar formas idénticas (que tienen campos idénticos)
En este caso, necesitamos cambiar el nombre de los campos, porque probablemente queremos diferentes valores en diferentes páginas. En PDF, un campo solo puede tener un valor único. Si combina formas idénticas, tiene múltiples visualizaciones del mismo campo, pero cada visualización mostrará el mismo valor (porque en realidad, solo hay un campo).
Echemos un vistazo al ejemplo de 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();
}
Como puede ver, el método
renameFields()
crea un nuevo documento en la memoria.
Ese documento se fusiona con otros documentos utilizando
PdfSmartCopy
.
Si usa
PdfCopy
aquí, su documento se hinchará (como pronto lo descubriremos).
Fusionar formas aplanadas
En
FillFlattenMerge1
, completamos los formularios con
PdfStamper
.
El resultado es un archivo PDF que se guarda en la memoria y se
PdfCopy
con
PdfCopy
.
Si bien este ejemplo está bien si fusiona diferentes formas, en realidad es un ejemplo de
cómo no hacerlo
(como se explica en el
video tutorial
).
FillFlattenMerge2 muestra cómo combinar formularios idénticos que se completan y aplanan correctamente:
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();
}
Estos son tres escenarios. Su pregunta no es clara para nadie más que para decidir qué escenario es el más adecuado para sus necesidades. Le sugiero que se tome el tiempo de aprender antes de codificar. Mire el video, pruebe los ejemplos y, si aún tiene dudas, podrá publicar una pregunta más inteligente.