如何在Java中将两个PDF文件合并为一个?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3585329/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 02:11:49  来源:igfitidea点击:

How to merge two PDF files into one in Java?

javapdfpdfbox

提问by Lipis

I want to merge many PDF files into one using PDFBoxand this is what I've done:

我想使用PDFBox将许多 PDF 文件合并为一个文件,这就是我所做的:

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

Where pdfFilesis an ArrayList<String>containing all the PDF files.

哪里pdfFiles是一个ArrayList<String>包含了所有的PDF文件。

When I'm running the above, I'm always getting:

当我运行上述程序时,我总是得到:

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

Am I doing something wrong? Is there any other way of doing it?

难道我做错了什么?有没有其他方法可以做到?

采纳答案by cherouvim

Why not use the PDFMergerUtilityof pdfbox?

为什么不使用pdfbox的PDFMergerUtility

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

回答by Michael Lloyd Lee mlk

A quick Google search returned this bug: "Bad file descriptor while saving a document w. imported PDFs".

一个快速的谷歌搜索返回了这个错误:“保存带有导入 PDF 的文档时文件描述符错误

It looks like you need to keep the PDFs to be merged open, until after you have saved and closed the combined PDF.

看起来您需要将要合并的 PDF 保持打开状态,直到您保存并关闭合并的 PDF 之后。

回答by Sabapathy

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)
    {

    }
}

}

回答by Dave W

If you want to combine two files where one overlays the other (example: document A is a template and document B has the text you want to put on the template), this works:

如果要合并两个文件,其中一个文件覆盖另一个文件(例如:文档 A 是模板,文档 B 包含要放在模板上的文本),则可以这样操作:

after creating "doc", you want to write your template (templateFile) on top of that -

创建“doc”后,您想在其上编写模板(templateFile)-

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

   overlay.overlay(watermarkDoc, doc);

回答by benito

This is a ready to use code, merging four pdf files with itext.jar from http://central.maven.org/maven2/com/itextpdf/itextpdf/5.5.0/itextpdf-5.5.0.jar, more on http://tutorialspointexamples.com/

这是一个随时可用的代码,将四个 pdf 文件与来自http://central.maven.org/maven2/com/itextpdf/itextpdf/5.5.0/itextpdf-5.5.0.jar 的itext.jar 合并,更多关于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();
    }
    }
}

回答by Ricardo Jl Rufino

Using iText (existing PDF in bytes)

使用 iText(以字节为单位的现有 PDF)

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

}

回答by arifng

Multiple pdf merged method using org.apache.pdfbox:

使用org.apache.pdfbox 的多个 pdf 合并方法:

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

From main program, call mergePDFFilesmethod using list of files and target file name.

在主程序中,使用文件列表和目标文件名调用mergePDFFiles方法。

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

After calling mergePDFFiles, load merged file

调用mergePDFFiles 后,加载合并文件

        File mergedFile = new File(mergedFileName);