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?

Lipis
quelle
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();
Cherouvim
quelle
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
29

Eine schnelle Google-Suche ergab den folgenden Fehler: "Fehlerhafter Dateideskriptor beim Speichern eines Dokuments mit importierten PDFs" .

Es sieht so aus, als müssten Sie die zusammenzuführenden PDF-Dateien geöffnet lassen, bis Sie die kombinierte PDF-Datei gespeichert und geschlossen haben.

Michael Lloyd Lee mlk
quelle
5
Obwohl die Post zwei Jahre alt war, löste dies das Problem. Du musst sie offen halten!
Lipis
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();
    }
    }
}
benito
quelle
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);
arifng
quelle
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)
    {

    }
}

}
Sabapathie
quelle
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);
Dave W.
quelle
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();

}
Ricardo Jl Rufino
quelle
Die OP ganz klar gesagt , „Ich habe viele PDF - Dateien in eine mit PDFBox zusammenführen möchten“ . iText ist keine PDFBox.
mkl