Qual è il modo più semplice per unire (lato server) una raccolta di documenti PDF in un unico grande documento PDF in JAVA

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

  •  01-07-2019
  •  | 
  •  

Domanda

Ho 3 documenti PDF generati al volo da una libreria legacy che utilizziamo e scritti su disco.Qual è il modo più semplice per il codice del mio server JAVA di acquisire questi 3 documenti e trasformarli in un lungo documento PDF in cui sono solo tutte le pagine del documento n. 1, seguite da tutte le pagine del documento n. 2, ecc.

Idealmente vorrei che ciò accadesse in memoria in modo da poterlo restituire come flusso al client, ma anche scriverlo su disco è un'opzione.

È stato utile?

Soluzione

@J D OConal, grazie per il suggerimento, l'articolo che mi hai inviato era molto obsoleto, ma mi ha indirizzato verso iText.Ho trovato questa pagina che spiega come fare esattamente ciò di cui ho bisogno:http://java-x.blogspot.com/2006/11/merge-pdf-files-with-itext.html

Grazie per le altre risposte, ma non voglio davvero dover generare altri processi se posso evitarlo, e il nostro progetto ha già itext.jar, quindi non aggiungerò alcuna dipendenza esterna

Ecco il codice che ho finito per scrivere:

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();
            }
        }
    }
}

Altri suggerimenti

ho usato pdftk con grande effetto.È un'applicazione esterna che dovrai eseguire dalla tua app Java.

iText sembra essere cambiato e ora ha requisiti di licenza commerciale, oltre a un aiuto non così valido (vuoi documentazione?Acquista il nostro libro!).

Alla fine abbiamo trovato PDFSharp http://www.pdfsharp.net/ e usarlo.L'esempio per concatenare più documenti PDF insieme è semplice e facile da seguire: http://www.pdfsharp.net/wiki/ConcatenateDocuments-sample.ashx

Goditi casuali

Guarda questo elenco di librerie PDF Java open source.

Controlla anche Questo articolo.

[Modificare:C'è sempre Ghostscript, che è facile da usare, ma chi vuole più dipendenze?]

PDFBox è di gran lunga il modo più semplice per raggiungere questo obiettivo, c'è un'utilità chiamata PDFMerger all'interno del codice che rende le cose molto semplici, mi è bastato un ciclo for e 2 righe di codice e tutto è fatto :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top