Skip to content

Instantly share code, notes, and snippets.

@JoelGeraci-Datalogics
Last active December 30, 2021 11:15
Show Gist options
  • Save JoelGeraci-Datalogics/04512853b541754bb23a to your computer and use it in GitHub Desktop.
Save JoelGeraci-Datalogics/04512853b541754bb23a to your computer and use it in GitHub Desktop.
Merging PDF Files Using the Datalogics PDF Java Toolkit
/*
* Copyright Datalogics, Inc. 2015
*/
package pdfjt.cookbook.combine;
import com.adobe.internal.io.ByteReader;
import com.adobe.internal.io.ByteWriter;
import com.adobe.internal.io.InputStreamByteReader;
import com.adobe.pdfjt.core.types.ASRectangle;
import com.adobe.pdfjt.pdf.document.PDFCatalog;
import com.adobe.pdfjt.pdf.document.PDFDocument;
import com.adobe.pdfjt.pdf.document.PDFOpenOptions;
import com.adobe.pdfjt.pdf.document.PDFSaveFullOptions;
import com.adobe.pdfjt.pdf.document.PDFVersion;
import com.adobe.pdfjt.pdf.interactive.PDFViewerPreferences;
import com.adobe.pdfjt.pdf.page.PDFPageLayout;
import com.adobe.pdfjt.pdf.page.PDFPageMode;
import com.adobe.pdfjt.services.manipulations.PMMOptions;
import com.adobe.pdfjt.services.manipulations.PMMService;
import java.io.File;
import java.io.FileInputStream;
import pdfjt.util.SampleFileServices;
/*
* Merge a set of PDFs found in an particular input directory into one new PDF
* that is written out to a particular output directory with the name of "MergedDocument.pdf"
*/
public class MergeDocuments {
private static final String inputDir = "cookbook/MergeDocuments/input";
private static final String outputDir = "cookbook/MergeDocuments/output";
private static final String outputFilename = "MergedDocument.pdf";
public static void main(String[] args) throws Exception {
/*
* Start by creating a new PDF document that will be used to merge the
* other documents into. The new document will contain a single blank
* page but we'll remove this just before saving the merged file.
*/
PDFDocument mergedDocument = PDFDocument.newInstance(new ASRectangle(
new double[] { 0, 0, 612, 792 }), PDFOpenOptions.newInstance());
/*
* Setting the initial view is not required. However, the PMMService
* which is used to merge the documents will also merge the bookmarks
* from the individual files. Setting the initial view to display the
* bookmarks makes it easier to see that the sample has worked
* correctly.
*/
setInitialView(mergedDocument, true, PDFPageLayout.SinglePage,
PDFPageMode.WithBookmarks);
/*
* Create the new PMMService that will be used to manipulate the pages.
*/
PMMService pmmService = new PMMService(mergedDocument);
try {
/*
* Add the files in the input directory to the new PDF file. This
* process will append the pages from each document to the end of
* the new document creating a continuous series of pages.
*
* Folders will be skipped.
*/
File root = new File(inputDir);
File[] list = root.listFiles();
// If there are no files, just return now!
if (list == null)
return;
for (File pdfFile : list) {
if (!pdfFile.isDirectory()) {
String pdfFileName = pdfFile.getName();
FileInputStream fis = new FileInputStream(pdfFile);
ByteReader byteReader = new InputStreamByteReader(fis);
PDFDocument pdfToAppend = PDFDocument.newInstance(
byteReader, PDFOpenOptions.newInstance());
/*
* Create the Bookmark Title String to imitate the behavior
* of Acrobat. This will be the title of the new bookmark
* that wraps the bookmarks in the source document before it
* is added after the last bookmark in the merged document.
* Acrobat uses the basefile name of the source PDF so we'll
* do that too.
*/
String documentBookmarkRootName = pdfFileName.substring(0,
pdfFileName.length() - 4);
/*
* Here's the interesting part. PMMOptions control what
* elements of the source document are copied into the
* target. "All" will copy bookmarks, links, annotations,
* layer content (though not the layers themselves), form
* fields, and structure.
*
* Form fields with the same name will be merged and assume
* the value of the first field encountered during the
* appends.
*
* Bookmark destinations and links will be automatically
* resolved.
*/
System.out.println("Appending " + pdfFileName
+ " to the end of " + outputFilename);
pmmService.appendPages(pdfToAppend,
documentBookmarkRootName,
PMMOptions.newInstanceAll());
}
}
/*
* Remove the first page. We don't need it anymore.
*/
mergedDocument.requirePages().removePage(
mergedDocument.requirePages().getPage(0));
/*
* Save the file
*/
ByteWriter outputWriter = SampleFileServices
.getRAFByteWriter(outputDir + File.separator
+ outputFilename);
mergedDocument.save(outputWriter,
PDFSaveFullOptions.newInstance(PDFVersion.v1_7));
System.out.println("Created " + outputFilename + " with "
+ mergedDocument.requirePages().getCount() + " pages");
} finally {
mergedDocument.close();
}
}
/**
* Sets the initial view of the PDF file passed.
*
* @param pdfDocument
* The PDFDocument object in question
* @param fitWindow
* Set the initial zoom of the PDF to fit page if true
* @param layout
* Sets the initial page layout in the PDF viewer
* @param mode
* Sets the initial page mode to display one of the navigational
* tabs in the PDF viewer
* @return none
*/
private static void setInitialView(PDFDocument pdfDocument,
boolean fitWindow, PDFPageLayout layout, PDFPageMode mode) {
try {
PDFCatalog catalog = pdfDocument.requireCatalog();
catalog.setPageLayout(layout);
catalog.setPageMode(mode);
PDFViewerPreferences pdfViewerPreferences = PDFViewerPreferences
.newInstance(pdfDocument);
pdfViewerPreferences.setFitWindow(fitWindow);
pdfDocument.setViewerPreferences(pdfViewerPreferences);
} catch (Exception e) {
}
}
}
@massi2016
Copy link

Hello @JoelGeraci-Datalogics thank you for sharing with us your solution, is it possible to send us the jars you used.

Thank's a lot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment