¿Cuál es la forma más sencilla de fusionar (del lado del servidor) una colección de documentos PDF en un documento PDF grande en JAVA?

StackOverflow https://stackoverflow.com/questions/90350

  •  01-07-2019
  •  | 
  •  

Pregunta

Tengo 3 documentos PDF que se generan sobre la marcha mediante una biblioteca heredada que usamos y se escriben en el disco.¿Cuál es la forma más fácil para que el código de mi servidor JAVA tome estos 3 documentos y los convierta en un documento PDF largo donde solo están todas las páginas del documento n.° 1, seguidas de todas las páginas del documento n.° 2, etc.?

Idealmente, me gustaría que esto suceda en la memoria para poder devolverlo como una secuencia al cliente, pero escribirlo en el disco también es una opción.

¿Fue útil?

Solución

@J D OConal, gracias por el consejo, el artículo que me enviaste estaba muy desactualizado, pero me indicó iText.Encontré esta página que explica cómo hacer exactamente lo que necesito:http://java-x.blogspot.com/2006/11/merge-pdf-files-with-itext.html

Gracias por las otras respuestas, pero realmente no quiero tener que generar otros procesos si puedo evitarlo, y nuestro proyecto ya tiene itext.jar, así que no agregaré ninguna dependencia externa.

Aquí está el código que terminé escribiendo:

public class PdfMergeHelper {

    /**
     * Merges the passed in PDFs, in the order that they are listed in the java.util.List.
     * Writes the resulting PDF out to the OutputStream provided.
     * 
     * Sample Usage:
     * List<InputStream> pdfs = new ArrayList<InputStream>();
     * pdfs.add(new FileInputStream("/location/of/pdf/OQS_FRSv1.5.pdf"));
     * pdfs.add(new FileInputStream("/location/of/pdf/PPFP-Contract_Genericv0.5.pdf"));
     * pdfs.add(new FileInputStream("/location/of/pdf/PPFP-Quotev0.6.pdf"));
     * FileOutputStream output = new FileOutputStream("/location/to/write/to/merge.pdf");
     * PdfMergeHelper.concatPDFs(pdfs, output, true);
     * 
     * @param streamOfPDFFiles the list of files to merge, in the order that they should be merged
     * @param outputStream the output stream to write the merged PDF to
     * @param paginate true if you want page numbers to appear at the bottom of each page, false otherwise
     */
    public static void concatPDFs(List<InputStream> streamOfPDFFiles, OutputStream outputStream, boolean paginate) {
        Document document = new Document();
        try {
            List<InputStream> pdfs = streamOfPDFFiles;
            List<PdfReader> readers = new ArrayList<PdfReader>();
            int totalPages = 0;
            Iterator<InputStream> iteratorPDFs = pdfs.iterator();

            // Create Readers for the pdfs.
            while (iteratorPDFs.hasNext()) {
                InputStream pdf = iteratorPDFs.next();
                PdfReader pdfReader = new PdfReader(pdf);
                readers.add(pdfReader);
                totalPages += pdfReader.getNumberOfPages();
            }
            // Create a writer for the outputstream
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);

            document.open();
            BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
            PdfContentByte cb = writer.getDirectContent(); // Holds the PDF
            // data

            PdfImportedPage page;
            int currentPageNumber = 0;
            int pageOfCurrentReaderPDF = 0;
            Iterator<PdfReader> iteratorPDFReader = readers.iterator();

            // Loop through the PDF files and add to the output.
            while (iteratorPDFReader.hasNext()) {
                PdfReader pdfReader = iteratorPDFReader.next();

                // Create a new page in the target for each source page.
                while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {
                    document.newPage();
                    pageOfCurrentReaderPDF++;
                    currentPageNumber++;
                    page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);
                    cb.addTemplate(page, 0, 0);

                    // Code for pagination.
                    if (paginate) {
                        cb.beginText();
                        cb.setFontAndSize(bf, 9);
                        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, "" + currentPageNumber + " of " + totalPages,
                                520, 5, 0);
                        cb.endText();
                    }
                }
                pageOfCurrentReaderPDF = 0;
            }
            outputStream.flush();
            document.close();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (document.isOpen()) {
                document.close();
            }
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }
}

Otros consejos

he usado pdftk con gran efecto.Es una aplicación externa que deberás ejecutar desde tu aplicación Java.

iText parece haber cambiado y ahora tiene requisitos de licencia comercial, además de una ayuda no tan buena (¿Quiere documentación?¡Compra nuestro libro!).

Terminamos encontrando PDFSharp http://www.pdfsharp.net/ y usando eso.El ejemplo para concatenar varios documentos pdf es simple y fácil de seguir: http://www.pdfsharp.net/wiki/ConcatenateDocuments-sample.ashx

Disfrute del azar

Mira esto lista de bibliotecas PDF de código abierto de Java.

También echa un vistazo Este artículo.

[Editar:Siempre existe Ghostscript, que es fácil de usar, pero ¿quién quiere más dependencias?]

PDFBox es, con mucho, la forma más fácil de lograr esto, hay una utilidad llamada PDFMerger dentro del código que hace las cosas muy fáciles, todo lo que me necesitó fue un bucle for y 2 líneas de código y listo :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top