2011-04-28 9 views
7

Estoy escribiendo un programa en Java que imprime archivos PDF de Bingo Cards. Cada página es una carta. Para hacerlo más fácil, creé una plantilla de archivo PDF con acrofields, de modo que el programa solo necesitará crear una copia de esta plantilla, llenar los acrofields con números y luego aplanarlos. A partir de ahora, puedo crear 1 tarjeta de bingo. Quiero tener varias páginas (por lo tanto, varias tarjetas) en un archivo PDF. Pero no tengo una idea de cómo hacer esto. Lo que leí es que un PDFStamper está asociado a un único objeto PDFReader. ¿Hay alguna manera de que pueda hacer esto sin recurrir a la creación de múltiples archivos PDF y combinarlos en uno (lo hice la última vez y encontré realmente lento) Gracias de antemano!Itext - ¿Cómo clonar páginas con acrofields?

Respuesta

13

Me tomó un tiempo resolver esto. No es la forma más eficiente de código, pero esto es esencialmente lo que hace:

  • crear un documento
  • para cada página (s) con un acrofield:
  • copiar la plantilla
  • rellenar el formulario
  • aplanar la forma
  • añadir la página

Aquí está mi aplicación que se puede tratar y modificar para adaptarse a sus necesidades: Método

private void createPdf() throws Exception { 
    Document doc = new Document(); 
    PdfSmartCopy copy = new PdfSmartCopy(doc, new FileOutputStream("result.pdf")); 
    doc.open(); 

    PdfReader reader; 
    PdfStamper stamper; 
    AcroFields form; 
    ByteArrayOutputStream baos; 

    for(int i = 0; i < getTotalPages(); i++) { 
     copyPdf(i); 

     reader = new PdfReader(String.format("%d%s", i, "template.pdf")); 
     baos = new ByteArrayOutputStream(); 
     stamper = new PdfStamper(reader, baos); 
     form = stamper.getAcroFields(); 
     //methods to fill forms 

     stamper.setFormFlattening(true); 
     stamper.close(); 

     reader = new PdfReader(baos.toByteArray()); 
     copy.addPage(copy.getImportedPage(reader, 1)); 
    } 

    doc.close(); 
} 

private void copyPdf(int currentPage) throws Exception { 
    PdfReader reader = new PdfReader("timesheet.pdf"); 
    Document doc = new Document(); 
    File file = new File(String.format("%d%s", currentPage, "template.pdf")); 
    file.deleteOnExit(); 
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(file)); 
    stamper.close(); 
} 

El copyPdf() crea archivos temporales que se utilizan para permitir el rellenado de formularios sin afectar a todo el documento. Si encuentra una manera más eficiente de hacerlo, hágamelo saber.

Además, he encontrado que en Mac Intel Based vs Windows Computer, la Mac completa esto mucho más rápido.

Si no se opone a la obtención de un libro de referencia para iText, recomendaría "iText in Action, Second Edition" de Bruno Lowagie. Es un gran libro y muy útil.

+0

+1 para la sugerencia libro – oers

+0

1 exactamente lo que necesito! ¡Gracias! Solo una nota, 'doc' en copyPdf no se usa :) – Jairo

+3

No debe necesitar 'copyPdf()' en absoluto. Y aunque lo hicieras, esa es una forma tremendamente ineficiente de copiar un archivo (que pasa a ser un PDF) de A a B. Incluso podrías usar el mismo 'PdfReader' para todas tus instancias diferentes de' PdfStamper', pero es probable que revele errores. * Estarás * casi seguro * bien usando varios lectores en el mismo archivo. –

1

lo tanto, aquí está el código sin necesidad de utilizar el método "copyPdf" de Zach, como sugirieron Marcos Storer y MAXarT:

private void createPdf() throws Exception { 
    Document doc = new Document(); 
    PdfSmartCopy copy = new PdfSmartCopy(doc, new FileOutputStream("result.pdf")); 
    doc.open(); 

    PdfReader mainReader = new PdfReader("timesheet.pdf"); 

    PdfReader reader; 
    PdfStamper stamper; 
    AcroFields form; 
    ByteArrayOutputStream baos; 

    for(int i = 0; i < getTotalPages(); i++) { 

     reader = new PdfReader(mainReader); 
     baos = new ByteArrayOutputStream(); 
     stamper = new PdfStamper(reader, baos); 
     AcroFields form = stamper.getAcroFields(); 

     //methods to fill forms 

     stamper.setFormFlattening(true); 
     stamper.close(); 

     reader = new PdfReader(baos.toByteArray()); 
     copy.addPage(copy.getImportedPage(reader, 1)); 
    } 

    doc.close(); 
}