Wie füge ich zwei PDF-Dateien in Java zu einer zusammen?


74

Ich möchte mit PDFBox viele PDF-Dateien zu einer zusammenführen, und das habe ich getan:

PDDocument document = new PDDocument();
for (String pdfFile: pdfFiles) {
    PDDocument part = PDDocument.load(pdfFile);
    List<PDPage> list = part.getDocumentCatalog().getAllPages();
    for (PDPage page: list) {
        document.addPage(page);
    }
    part.close();
}
document.save("merged.pdf");
document.close();

Wo pdfFilesist ein ArrayList<String>mit allen PDF-Dateien.

Wenn ich das oben genannte ausführe, bekomme ich immer:

org.apache.pdfbox.exceptions.COSVisitorException: Bad file descriptor

Mache ich etwas falsch? Gibt es eine andere Möglichkeit?


1
Jemand wies auf iText [ java-x.blogspot.com/2006/11/merge-pdf-files-with-itext.html] hin und löschte dann die Antwort. Es hat funktioniert und danke dafür.
Lipis

Der Link kann jemandem helfen, der nach einer Antwort sucht.
Java_Learner

Antworten:


131

Warum nicht die PDFMergerUtility von pdfbox verwenden?

PDFMergerUtility ut = new PDFMergerUtility();
ut.addSource(...);
ut.addSource(...);
ut.addSource(...);
ut.setDestinationFileName(...);
ut.mergeDocuments();

1
Funktioniert auch, aber ich habe die PDFBox auch zum Erstellen von PDF verwendet.
Lipis

Ermöglicht es das Zusammenführen einer PDF-Datei mit gescannten Bildern und einer PDF-Datei, die geschrieben wurde?
Ragesh Kr

3
@RageshKr: Soweit ich weiß, werden alle PDF-Dateien unabhängig von ihrem Inhalt zusammengeführt.
Cherouvim

1
Gibt es eine Möglichkeit, Seite-Nr. Auf jeder Seite für das resultierende PDF zu erwähnen?
Prateek Singh

Kann es verwendet werden, wenn die PDF-Dateien Passwörter haben?
Codierer


11

Dies ist ein gebrauchsfertiger Code, bei dem vier PDF-Dateien mit itext.jar von http://central.maven.org/maven2/com/itextpdf/itextpdf/5.5.0/itextpdf-5.5.0.jar zusammengeführt werden. Weitere Informationen finden Sie unter http : //tutorialspointexamples.com/

import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;

/**
 * This class is used to merge two or more 
 * existing pdf file using iText jar.
 */
public class PDFMerger {

static void mergePdfFiles(List<InputStream> inputPdfList,
        OutputStream outputStream) throws Exception{
    //Create document and pdfReader objects.
    Document document = new Document();
    List<PdfReader> readers = 
            new ArrayList<PdfReader>();
    int totalPages = 0;

    //Create pdf Iterator object using inputPdfList.
    Iterator<InputStream> pdfIterator = 
            inputPdfList.iterator();

    // Create reader list for the input pdf files.
    while (pdfIterator.hasNext()) {
            InputStream pdf = pdfIterator.next();
            PdfReader pdfReader = new PdfReader(pdf);
            readers.add(pdfReader);
            totalPages = totalPages + pdfReader.getNumberOfPages();
    }

    // Create writer for the outputStream
    PdfWriter writer = PdfWriter.getInstance(document, outputStream);

    //Open document.
    document.open();

    //Contain the pdf data.
    PdfContentByte pageContentByte = writer.getDirectContent();

    PdfImportedPage pdfImportedPage;
    int currentPdfReaderPage = 1;
    Iterator<PdfReader> iteratorPDFReader = readers.iterator();

    // Iterate and process the reader list.
    while (iteratorPDFReader.hasNext()) {
            PdfReader pdfReader = iteratorPDFReader.next();
            //Create page and add content.
            while (currentPdfReaderPage <= pdfReader.getNumberOfPages()) {
                  document.newPage();
                  pdfImportedPage = writer.getImportedPage(
                          pdfReader,currentPdfReaderPage);
                  pageContentByte.addTemplate(pdfImportedPage, 0, 0);
                  currentPdfReaderPage++;
            }
            currentPdfReaderPage = 1;
    }

    //Close document and outputStream.
    outputStream.flush();
    document.close();
    outputStream.close();

    System.out.println("Pdf files merged successfully.");
}

public static void main(String args[]){
    try {
        //Prepare input pdf file list as list of input stream.
        List<InputStream> inputPdfList = new ArrayList<InputStream>();
        inputPdfList.add(new FileInputStream("..\\pdf\\pdf_1.pdf"));
        inputPdfList.add(new FileInputStream("..\\pdf\\pdf_2.pdf"));
        inputPdfList.add(new FileInputStream("..\\pdf\\pdf_3.pdf"));
        inputPdfList.add(new FileInputStream("..\\pdf\\pdf_4.pdf"));


        //Prepare output stream for merged pdf file.
        OutputStream outputStream = 
                new FileOutputStream("..\\pdf\\MergeFile_1234.pdf");

        //call method to merge pdf files.
        mergePdfFiles(inputPdfList, outputStream);     
    } catch (Exception e) {
        e.printStackTrace();
    }
    }
}

3
Die Frage ist eindeutig mit pdfbox gekennzeichnet . Sie präsentieren eine Lösung für itext . Daher ist Ihre Antwort nicht zum Thema. (Das heißt, Ihre iText-Lösung ist auch eine schlechte, von der iText-Entwickler normalerweise
abraten,

Dann sollte der Titel "Wie man zwei PDF-Dateien in Java mit PdfBox zu einer zusammenführt" sein
Lluis Martinez

3
Zusätzlich kommt iText mit einer bösen Lizenz.
Daniel Bo

Dieses Beispiel heißt IncorrectExample, da Sie auf diese Weise normalerweise nicht das Problem des Rotierens von Seiten oder des Zusammenführens von Dokumenten lösen. Der richtige Weg ist NICHT, Document / PdfWriter zu verwenden, sondern PdfStamper, PdfCopy oder PdfSmartCopy. Allerdings: In der oben genannten Frage sind die Umstände sehr speziell und die Verwendung dieses Beispiels unter diesen Umständen ist gerechtfertigt: developer.itextpdf.com/examples/merging-pdf-documents-itext5/…
victorpacheco3107

5

Methode zum Zusammenführen mehrerer PDF- Dateien mit org.apache.pdfbox :

public void mergePDFFiles(List<File> files,
                          String mergedFileName) {
    try {
        PDFMergerUtility pdfmerger = new PDFMergerUtility();
        for (File file : files) {
            PDDocument document = PDDocument.load(file);
            pdfmerger.setDestinationFileName(mergedFileName);
            pdfmerger.addSource(file);
            pdfmerger.mergeDocuments(MemoryUsageSetting.setupTempFileOnly());
            document.close();
        }
    } catch (IOException e) {
        logger.error("Error to merge files. Error: " + e.getMessage());
    }
}

Rufen Sie im Hauptprogramm die Methode mergePDFFiles mit der Liste der Dateien und dem Namen der Zieldatei auf.

        String mergedFileName = "Merged.pdf";
        mergePDFFiles(files, mergedFileName);

Laden Sie nach dem Aufruf von mergePDFFiles die zusammengeführte Datei

        File mergedFile = new File(mergedFileName);

4
package article14;

import java.io.File;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.util.PDFMergerUtility;

public class Pdf
{
    public static void main(String args[])
    {
        new Pdf().createNew();
        new Pdf().combine();
        }

    public void combine()
    {
        try
        {
        PDFMergerUtility mergePdf = new PDFMergerUtility();
        String folder ="pdf";
        File _folder = new File(folder);
        File[] filesInFolder;
        filesInFolder = _folder.listFiles();
        for (File string : filesInFolder)
        {
            mergePdf.addSource(string);    
        }
    mergePdf.setDestinationFileName("Combined.pdf");
    mergePdf.mergeDocuments();
        }
        catch(Exception e)
        {

        }  
    }

public void createNew()
{
    PDDocument document = null;
    try
    {
        String filename="test.pdf";
        document=new PDDocument();
        PDPage blankPage = new PDPage();
        document.addPage( blankPage );
        document.save( filename );
    }
    catch(Exception e)
    {

    }
}

}

Das Verschlucken von Ausnahmen ist ein schlechtes Muster. catch (Ausnahme e) {}
Lluis Martinez

1

Wenn Sie zwei Dateien kombinieren möchten, bei denen eine die andere überlagert (Beispiel: Dokument A ist eine Vorlage und Dokument B enthält den Text, den Sie in die Vorlage einfügen möchten), funktioniert dies:

Nachdem Sie "doc" erstellt haben, möchten Sie Ihre Vorlage (templateFile) darüber schreiben -

   PDDocument watermarkDoc = PDDocument.load(getServletContext()
                .getRealPath(templateFile));
   Overlay overlay = new Overlay();

   overlay.overlay(watermarkDoc, doc);

0

Verwenden von iText (vorhandenes PDF in Bytes)

    public static byte[] mergePDF(List<byte[]> pdfFilesAsByteArray) throws DocumentException, IOException {

    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    Document document = null;
    PdfCopy writer = null;

    for (byte[] pdfByteArray : pdfFilesAsByteArray) {

        try {
            PdfReader reader = new PdfReader(pdfByteArray);
            int numberOfPages = reader.getNumberOfPages();

            if (document == null) {
                document = new Document(reader.getPageSizeWithRotation(1));
                writer = new PdfCopy(document, outStream); // new
                document.open();
            }
            PdfImportedPage page;
            for (int i = 0; i < numberOfPages;) {
                ++i;
                page = writer.getImportedPage(reader, i);
                writer.addPage(page);
            }
        }

        catch (Exception e) {
            e.printStackTrace();
        }

    }

    document.close();
    outStream.close();
    return outStream.toByteArray();

}

Die OP ganz klar gesagt , „Ich habe viele PDF - Dateien in eine mit PDFBox zusammenführen möchten“ . iText ist keine PDFBox.
mkl
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.