package com.appirio;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import org.apache.poi.hslf.model.Slide;
import org.apache.poi.hslf.usermodel.SlideShow;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.tika.config.TikaConfig;
import org.apache.tika.detect.DefaultDetector;
import org.apache.tika.detect.Detector;
import org.apache.tika.extractor.ContainerExtractor;
import org.apache.tika.extractor.EmbeddedDocumentExtractor;
import org.apache.tika.extractor.EmbeddedResourceHandler;
import org.apache.tika.extractor.ParserContainerExtractor;
import org.apache.tika.io.IOUtils;
import org.apache.tika.io.TikaInputStream;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.mime.MediaType;
import org.apache.tika.mime.MimeTypeException;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.html.simpleparser.HTMLWorker;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
/**
* @author jesus
*
*/
public class PDFCombiner {
// unique identifier for generated files
private String uniqueId = null;
// generated pdf directory (generated at runtime)
private String generatedPDFDir = null;
// list of temporary files that will be deleted
private List<String> temporaryFilesToBeDeleted = null;
private static final String PDFS_TEMPLATES_DIR = System.getenv("PDFS_TEMPLATES_DIR");
/**
* Creates a directory to store generated pdf and temporary files (as images, etc.)
* @throws Exception
*/
public String getGeneratedPDFDir() throws Exception {
if(generatedPDFDir == null) {
generatedPDFDir = System.getenv("GENERATED_PDFS_DIR") + File.separator + this.getUniqueId();
if(!new File(generatedPDFDir).mkdirs())
{
throw new Exception("Could not create working directory " + generatedPDFDir);
}
}
return generatedPDFDir;
}
/**
* Returns a unique id for this job
* @return
*/
public String getUniqueId() {
if(uniqueId == null) {
uniqueId = String.valueOf(Calendar.getInstance().getTimeInMillis());
}
return uniqueId;
}
/**
* Return combined PDF file name
* @throws Exception
*/
public String getCombinedFileName() throws Exception {
return this.getGeneratedPDFDir() + File.separator + this.getUniqueId() + ".pdf";
}
/**
* Remove generated files
* @throws Exception
*/
public void deleteGeneratedFiles() throws Exception {
// delete files
for(File file : new File(this.getGeneratedPDFDir()).listFiles()) {
if(!file.delete()) {
throw new Exception("Could not delete file " + file.getAbsolutePath());
}
}
// delete parent directory
if(!new File(this.getGeneratedPDFDir()).delete()) {
throw new Exception("Could not delete directory " + this.getGeneratedPDFDir());
}
}
/**
* Combine multiple files into a single PDF. Accepts office formats: doc, docx, xls, xlsx, ppt. PDF file format. Image formats accepted by itext.
*/
public String combine(PDFCombinerArguments pdfCombinerArguments) throws Exception {
String combinedFileName = null;
// merge pdf
LinkedHashMap<String, PDFCombinerFile> pdfFileList = new LinkedHashMap<String, PDFCombinerFile>();
temporaryFilesToBeDeleted = new ArrayList<String>();
// create pdf for contents
if(pdfCombinerArguments.getContents() != null && !pdfCombinerArguments.isExcludeFlightLines()) {
LinkedHashMap<String, PDFCombinerFile> contentsPdfsList = createPdfsForCollection(pdfCombinerArguments.getContents());
pdfFileList.putAll(contentsPdfsList);
// every item in content is a proposal report. set IsProposalReport to true.
for(PDFCombinerFile pdfCombinerFile : pdfCombinerArguments.getContents()) {
pdfCombinerFile.setIsProposalReport(true);
}
}
// create pdf for appendixes
if(pdfCombinerArguments.getAppendixes() != null) {
LinkedHashMap<String, PDFCombinerFile> appendixesPdfsList = createPdfsForCollection(pdfCombinerArguments.getAppendixes());
pdfFileList.putAll(appendixesPdfsList);
}
// combine temporary pdfs into a single pdf
if(pdfFileList.size() > 0 || pdfCombinerArguments.isExcludeFlightLines()) {
// create a top part list for storing references to coverpage and toc
LinkedHashMap<String, PDFCombinerFile> pdfCompleteFileList = new LinkedHashMap<String, PDFCombinerFile>();
// Resulting pdf
OutputStream out = new FileOutputStream(new File(this.getCombinedFileName()));
// coverage page
if(pdfCombinerArguments.isShowCoverPage()) {
String coverpageFileName = getGeneratedCoverpagePdfPath(pdfCombinerArguments);
temporaryFilesToBeDeleted.add(coverpageFileName);
pdfCompleteFileList.put(coverpageFileName, null);
}
// table of contents
if(pdfCombinerArguments.isShowTableOfContents() && pdfFileList.size() > 0 ){//!pdfCombinerArguments.isExcludeFlightLines()) {
String tocFileName = getGeneratedTOCPdfPath(pdfCombinerArguments);
temporaryFilesToBeDeleted.add(tocFileName);
pdfCompleteFileList.put(tocFileName, null);
}
// add to final list
if(pdfFileList.size() > 0)
pdfCompleteFileList.putAll(pdfFileList);
// merge pdfs
doMerge(pdfCombinerArguments, pdfCompleteFileList, out);
deleteTempFiles(temporaryFilesToBeDeleted);
combinedFileName = this.getCombinedFileName();
//System.out.println(" combinedFileName: " + combinedFileName);
}
// return combined pdf filename
return combinedFileName;
}
private LinkedHashMap<String, PDFCombinerFile> createPdfsForCollection(List<PDFCombinerFile> files) throws Exception {
LinkedHashMap<String, PDFCombinerFile> pdfFileList = new LinkedHashMap<String, PDFCombinerFile>();
// iterate passed files parameter. use filename extension to determine conversion method.
for(PDFCombinerFile file : files) {
if(file.getFileName().toLowerCase().endsWith("pdf")) {
pdfFileList.put(file.getFileName(), file);
file.setNumberOfPages(getNumberOfPagesInPdf(file.getFileName()));
} else if(file.getFileName().toLowerCase().endsWith("doc") || file.getFileName().toLowerCase().endsWith("docx") || file.getFileName().toLowerCase().endsWith("xls") || file.getFileName().toLowerCase().endsWith("xlsx")) {
String fileName = convertOfficeFileToPDF(file.getFileName());
temporaryFilesToBeDeleted.add(fileName);
pdfFileList.put(fileName, file);
file.setNumberOfPages(getNumberOfPagesInPdf(fileName));
} else if(file.getFileName().toLowerCase().endsWith("ppt")) {
LinkedHashMap<String, PDFCombinerFile> pptPdfs = convertPPT(file.getFileName(), file);
pdfFileList.putAll(pptPdfs);
file.setNumberOfPages(pptPdfs.size());
} else {
String fileName = convertImageToPDF(file.getFileName());
temporaryFilesToBeDeleted.add(fileName);
pdfFileList.put(fileName, file);
file.setNumberOfPages(getNumberOfPagesInPdf(fileName));
}
}
return pdfFileList;
}
/**
* Returns number of pages in specified PDF file
*/
private Integer getNumberOfPagesInPdf(String pdfFileName) throws IOException {
InputStream in = new FileInputStream(pdfFileName);
PdfReader reader = new PdfReader(in);
return reader.getNumberOfPages();
}
/**
* Convert PPT to pdf
* @throws Exception
*/
private LinkedHashMap<String, PDFCombinerFile> convertPPT(String file, PDFCombinerFile pdfCombinerFile) throws Exception {
FileInputStream is = new FileInputStream(file);
SlideShow ppt = new SlideShow(is);
is.close();
LinkedHashMap<String, PDFCombinerFile> generatedImageFiles = new LinkedHashMap<String, PDFCombinerFile>();
Dimension pgsize = ppt.getPageSize();
Slide[] slide = ppt.getSlides();
for (int i = 0; i < slide.length; i++) {
BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics();
//clear the drawing area
graphics.setPaint(Color.white);
graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
//render
slide[i].draw(graphics);
//save the output
File tempFile = File.createTempFile("tmp-slide-" + (i+1), ".png", new File(this.getGeneratedPDFDir()));
FileOutputStream out = new FileOutputStream(tempFile);
javax.imageio.ImageIO.write(img, "png", out);
out.close();
// add file to list
String pdfFile = convertImageToPDF(tempFile.getAbsolutePath());
generatedImageFiles.put(pdfFile, pdfCombinerFile);
}
return generatedImageFiles;
}
/**
* Convert Office file format to pdf
* @param file
* @throws Exception
*/
private String convertOfficeFileToPDF(String file) throws Exception {
String result = getXML(file).xml;
ContainerExtractor extractor = new ParserContainerExtractor();
TrackingHandler handler;
handler = process(file, extractor, false);
//System.out.println(" result... ");
//System.out.println(result);
String directory = new File(this.getGeneratedPDFDir()).getAbsolutePath() + File.separator;
result = result.replace("embedded:", directory);
if(handler.filenames.size() > 0) {
//System.out.println(" result (after): " + result);
}
Document document = new Document();
File tempFile = File.createTempFile("temp_", ".pdf", new File(this.getGeneratedPDFDir()));
String generatedPDF = tempFile.getAbsolutePath();// getGeneratedPDFDir() + "\\NonPDFContent.pdf";
PdfWriter.getInstance(document, new FileOutputStream(generatedPDF));
document.open();
// add result elements to pdf
List<Element> objects
= HTMLWorker.parseToList(
new StringReader(result), null, null);
for (Element element : objects) {
document.add(element);
}
// closes document
document.close();
return generatedPDF;
}
/**
* Extaract embedded files from document
*/
private class FileEmbeddedDocumentExtractor implements EmbeddedDocumentExtractor {
private int count = 0;
private final TikaConfig config = TikaConfig.getDefaultConfig();
private String generatedPDFDir;
public FileEmbeddedDocumentExtractor(String generatedPDFDir) {
this.generatedPDFDir = generatedPDFDir;
}
@Override
public void parseEmbedded(InputStream inputStream, ContentHandler contentHandler, Metadata metadata, boolean outputHtml)
throws SAXException, IOException {
// base name
String name = metadata.get(Metadata.RESOURCE_NAME_KEY);
// create name if name is not available
if (name == null) {
name = "file" + count++;
}
// determine content type
MediaType contentType = detector.detect(inputStream, metadata);
if (name.indexOf('.')==-1 && contentType!=null) {
try {
name += config.getMimeRepository().forName(
contentType.toString()).getExtension();
} catch (MimeTypeException e) {
e.printStackTrace();
}
}
// to global generated pdf dir
File outputFile = new File(this.getGeneratedPDFDir(), name);
File parent = outputFile.getParentFile();
if (!parent.exists()) {
if (!parent.mkdirs()) {
throw new IOException("unable to create directory \"" + parent + "\"");
}
}
//System.out.println("Extracting '"+name+"' ("+contentType+") to " + outputFile);
// copy tika files to outputFile location
FileOutputStream os = new FileOutputStream(outputFile);
if (inputStream instanceof TikaInputStream) {
TikaInputStream tin = (TikaInputStream) inputStream;
if (tin.getOpenContainer() != null && tin.getOpenContainer() instanceof DirectoryEntry) {
POIFSFileSystem fs = new POIFSFileSystem();
copy((DirectoryEntry) tin.getOpenContainer(), fs.getRoot());
fs.writeFilesystem(os);
} else {
IOUtils.copy(inputStream, os);
}
} else {
IOUtils.copy(inputStream, os);
}
os.close();
}
@Override
public boolean shouldParseEmbedded(Metadata arg0) {
return true;
}
protected void copy(DirectoryEntry sourceDir, DirectoryEntry destDir)
throws IOException {
for (org.apache.poi.poifs.filesystem.Entry entry : sourceDir) {
if (entry instanceof DirectoryEntry) {
// Need to recurse
DirectoryEntry newDir = destDir.createDirectory(entry.getName());
copy((DirectoryEntry) entry, newDir);
} else {
// Copy entry
InputStream contents = new DocumentInputStream((DocumentEntry) entry);
try {
destDir.createDocument(entry.getName(), contents);
} finally {
contents.close();
}
}
}
}
// get generated pdf dir
private String getGeneratedPDFDir() {
return this.generatedPDFDir;
}
}
/** Inner class to add a header and a footer. */
static class HeaderFooter extends PdfPageEventHelper {
// start page count at this page
int startPageNumber = 0;
public HeaderFooter(int startPageNumber) {
this.startPageNumber = startPageNumber;
}
public void onEndPage (PdfWriter writer, Document document) {
Rectangle rect = writer.getPageSize();
int contentPage = writer.getPageNumber() - this.startPageNumber;
if(contentPage > 0) {
ColumnText.showTextAligned(writer.getDirectContent(),
Element.ALIGN_LEFT,
new Phrase(0.0F, String.format("Page %d", contentPage), new Font(FontFamily.HELVETICA, 7)),
rect.getLeft() + 10, rect.getBottom() + 18, 0);
}
}
}
static class AEFooter extends PdfPageEventHelper {
// start page count at this page
int startPageNumber = 0;
String aeName = "";
public AEFooter(int startPageNumber, String aeName) {
this.startPageNumber = startPageNumber;
this.aeName = aeName.substring(0, aeName.indexOf("\n"));
}
public void onEndPage (PdfWriter writer, Document document) {
Rectangle rect = writer.getPageSize();
int contentPage = writer.getPageNumber() - this.startPageNumber;
//System.out.println("AE Name->"+ aeName);
if(contentPage > 0) {
ColumnText.showTextAligned(writer.getDirectContent(),
Element.ALIGN_CENTER,
new Phrase(0.0F, String.format("Prepared by: %s", aeName), new Font(FontFamily.HELVETICA, 7)),
(rect.getLeft() + rect.getRight()) / 2, rect.getBottom() + 18, 0);
}
}
}
static class DateTimeFooter extends PdfPageEventHelper {
// start page count at this page
int startPageNumber = 0;
private String dateTimeStamp;
public DateTimeFooter(String dateTimeStamp, int startPageNumber) {
this.startPageNumber = startPageNumber;
setDateTimeStamp(dateTimeStamp);
}
public void onEndPage (PdfWriter writer, Document document) {
Rectangle rect = writer.getPageSize();
int contentPage = writer.getPageNumber() - this.startPageNumber;
if(contentPage > 0) {
//System.out.println(" getDateTimeStamp(): " + getDateTimeStamp() + " contentPage: " + contentPage);
ColumnText.showTextAligned(writer.getDirectContent(),
Element.ALIGN_RIGHT, new Phrase(0.0F, String.format("%s", getDateTimeStamp()), new Font(FontFamily.HELVETICA, 7)),
rect.getRight() - 20, rect.getBottom() + 18, 0);
}
}
public String getDateTimeStamp() {
return dateTimeStamp;
}
public void setDateTimeStamp(String dateTimeStamp) {
this.dateTimeStamp = dateTimeStamp;
}
}
// set xml contents
private static class XMLResult {
public final String xml;
public XMLResult(String xml, Metadata metadata) {
this.xml = xml;
}
}
Detector detector;
// get conents as xml
private XMLResult getXML(String filePath) throws Exception {
InputStream input = null;
Metadata metadata = new Metadata();
detector = new DefaultDetector();
Parser parser = new AutoDetectParser(detector);
// get xml contents from metadata
StringWriter sw = new StringWriter();
SAXTransformerFactory factory = (SAXTransformerFactory)
SAXTransformerFactory.newInstance();
TransformerHandler handler = factory.newTransformerHandler();
handler.getTransformer().setOutputProperty(OutputKeys.METHOD, "xml");
handler.getTransformer().setOutputProperty(OutputKeys.INDENT, "no");
handler.setResult(new StreamResult(sw));
ParseContext context = new ParseContext();
context.set(Parser.class, parser);
context.set(EmbeddedDocumentExtractor.class, new FileEmbeddedDocumentExtractor(this.getGeneratedPDFDir()));
input =new FileInputStream(new File(filePath));
try {
parser.parse(input, handler, metadata, context);
return new XMLResult(sw.toString(), metadata);
} finally {
input.close();
}
}
/**
* Convert an image to PDF
* @throws DocumentException
* @throws MalformedURLException
* @throws IOException
* @throws Exception
*/
private String convertImageToPDF(String file) throws DocumentException, MalformedURLException, IOException, Exception {
Image image1 = Image.getInstance(file);
Document document = new Document();
//if you would have a chapter indentation
int indentation = 0;
//whatever
// scale to fit page size
float scaler = ((document.getPageSize().getWidth() - document.leftMargin()
- document.rightMargin() - indentation) / image1.getWidth()) * 100;
image1.scalePercent(scaler);
// give it a name
File tempFile = File.createTempFile("temp_", ".pdf", new File(this.getGeneratedPDFDir()));
// get absolute path
String generatedPDF = tempFile.getAbsolutePath();
// add content to pdf
PdfWriter.getInstance(document, new FileOutputStream(generatedPDF));
document.open();
document.add(image1);
// closes document
document.close(); // no need to close PDFwriter?
return generatedPDF;
}
// embedded content detection handler
private static class TrackingHandler implements EmbeddedResourceHandler {
public List<String> filenames = new ArrayList<String>();
public List<MediaType> mediaTypes = new ArrayList<MediaType>();
public void handle(String filename, MediaType mediaType,
InputStream stream) {
filenames.add(filename);
mediaTypes.add(mediaType);
}
}
private TikaInputStream getTestFile(String filename) throws Exception {
InputStream input = new FileInputStream(new File(filename));
return TikaInputStream.get(input);
}
// return a tracking handler for a filename. (embedded content detection)
private TrackingHandler process(String filename, ContainerExtractor extractor, boolean recurse) throws Exception {
TikaInputStream stream = getTestFile(filename);
try {
// Process it
TrackingHandler handler = new TrackingHandler();
if(recurse) {
extractor.extract(stream, extractor, handler);
} else {
extractor.extract(stream, null, handler);
}
// So they can check what happened
return handler;
} finally {
stream.close();
}
}
private void deleteTempFiles(List<String> tempFiles) {
for(String tempFile : tempFiles) {
new File(tempFile).delete();
}
}
private static int getStartPageNumber(PDFCombinerArguments pdfCombinerArguments) {
int start = 0;
if(pdfCombinerArguments.isShowCoverPage()) start++;
if(pdfCombinerArguments.isShowTableOfContents()) start++;
return start;
}
/**
* Merge multiple pdf into one pdf
*
* @param list of pdf file names to be merged
* @param outputStream output file output stream
* @throws DocumentException
* @throws IOException
*/
private static void doMerge(PDFCombinerArguments pdfCombinerArguments, LinkedHashMap<String, PDFCombinerFile> pdfFileList, OutputStream outputStream)
throws DocumentException, IOException {
Document document = new Document();
document.setPageSize(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(document, outputStream);
writer.setBoxSize("art", PageSize.A4);
int startPageNo = getStartPageNumber(pdfCombinerArguments);
if(pdfCombinerArguments.isShowPageNumbering()) {
HeaderFooter event = new HeaderFooter(startPageNo);
writer.setPageEvent(event);
}
AEFooter aeEvent;
if(pdfCombinerArguments.getMarketContactInformation() != null)
aeEvent = new AEFooter(startPageNo, pdfCombinerArguments.getMarketContactInformation());
else
aeEvent = new AEFooter(startPageNo, pdfCombinerArguments.getClientContactInformation());
writer.setPageEvent(aeEvent);
if(pdfCombinerArguments.isShowTimeAndDateStamp()) {
DateTimeFooter dateTimeFooterEvent = new DateTimeFooter(pdfCombinerArguments.getDateTimeStamp(), startPageNo);
writer.setPageEvent(dateTimeFooterEvent);
}
document.open();
PdfContentByte cb = writer.getDirectContent();
for (Map.Entry<String, PDFCombinerFile> entry : pdfFileList.entrySet()) {
String pdfFileName = entry.getKey();
//System.out.println(" key: " + pdfFileName);
InputStream in = new FileInputStream(pdfFileName);
// get pdf combiner file
PDFCombinerFile pdfCombinerFile = pdfFileList.get(pdfFileName);
// get reader
PdfReader reader = new PdfReader(in);
int numberOfPages = reader.getNumberOfPages();
for (int i = 1; i <= numberOfPages; i++) {
//import the page from source pdf
PdfImportedPage page = writer.getImportedPage(reader, i);
// set page size
if(pdfCombinerFile != null && pdfCombinerFile.isProposalReport()) {
//System.out.println(" setting proposal page size");
// if file is a proposal report, set a page size
float width = page.getWidth();
float height = page.getHeight();
document.setPageSize(new Rectangle(width, height));
//, scale, 0, 0, scale, x, y);
//add the page to the destination pdf
document.newPage();
float factor = .9f; // scale factor
float offsetY = (page.getHeight() - (page.getHeight() * factor));
//System.out.println(" offsetY: " + offsetY);
float scaledWidth = page.getWidth() * factor;
float positionX = (page.getWidth() - scaledWidth) / 2;
//System.out.println(" positionX: " + positionX);
cb.addTemplate(page, factor, 0, 0, factor, positionX, offsetY);
} else {
document.setPageSize(page.getBoundingBox());
//add the page to the destination pdf
document.newPage();
cb.addTemplate(page, 0, 0);
}
// show title?
if(pdfCombinerFile != null && pdfCombinerFile.isShowTitle()) {
document.add(new Paragraph(pdfCombinerFile.getTitle()));
}
}
}
outputStream.flush();
document.close();
outputStream.close();
}
private String getGeneratedCoverpagePdfPath(PDFCombinerArguments pdfCombinerArguments) throws IOException, Exception {
String pdfTemplate = PDFS_TEMPLATES_DIR + File.separator + "coverpage.pdf";
File tempFile = File.createTempFile("temp_", ".pdf", new File(this.getGeneratedPDFDir()));
PdfReader pdfTemplatePdfReader = new PdfReader(pdfTemplate);
FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
PdfStamper stamper = new PdfStamper(pdfTemplatePdfReader, fileOutputStream);
stamper.setFormFlattening(true);
stamper.getAcroFields().setField("proposalTitle", pdfCombinerArguments.getTitle());
stamper.getAcroFields().setField("proposalSubtitle", pdfCombinerArguments.getSubTitle());
stamper.getAcroFields().setField("clientCompanyName", pdfCombinerArguments.getClientCompanyName());
stamper.getAcroFields().setField("clientContactInformation", pdfCombinerArguments.getClientContactInformation());
stamper.getAcroFields().setField("agencyName", pdfCombinerArguments.getAgencyName());
stamper.getAcroFields().setField("agencyContactInformation", pdfCombinerArguments.getAgencyContactInformation());
stamper.getAcroFields().setField("marketName", pdfCombinerArguments.getMarketName());
stamper.getAcroFields().setField("marketContactInformation", pdfCombinerArguments.getMarketContactInformation());
stamper.getAcroFields().setField("versionNumber", pdfCombinerArguments.getVersionNumber());
stamper.close();
pdfTemplatePdfReader.close();
//System.out.println(tempFile.getAbsolutePath());
return tempFile.getAbsolutePath();
}
// generate toc pdf
private String getGeneratedTOCPdfPath(PDFCombinerArguments pdfCombinerArguments) throws IOException, Exception {
String pdfTemplate = PDFS_TEMPLATES_DIR + File.separator + "table_of_contents.pdf";
File tempFile = File.createTempFile("temp_", ".pdf", new File(this.getGeneratedPDFDir()));
PdfReader pdfTemplatePdfReader = new PdfReader(pdfTemplate);
FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
PdfStamper stamper = new PdfStamper(pdfTemplatePdfReader, fileOutputStream);
stamper.setFormFlattening(true);
if(pdfCombinerArguments.getPdfCombinerContentEntryList() != null && !pdfCombinerArguments.isExcludeFlightLines()) {
int i = 0;
for(PDFCombinerContentEntry pdfCombinerContentEntry : pdfCombinerArguments.getPdfCombinerContentEntryList()) {
// set title
String titleFieldName = String.format("ContentTitle%s", i + 1);
stamper.getAcroFields().setField(titleFieldName, pdfCombinerContentEntry.getTitle());
// set description
String contentDescriptionFieldName = String.format("ContentDescription%s", i + 1);
stamper.getAcroFields().setField(contentDescriptionFieldName, pdfCombinerContentEntry.getDescription());
// set page number
String pageNumberFieldName = String.format("ContentPage%s", i + 1);
String pageNumber = String.valueOf(pdfCombinerContentEntry.getPageNumber());
stamper.getAcroFields().setField(pageNumberFieldName, pageNumber);
// for shipping instructions page override all field values
if("Shipping Instructions".equals(pdfCombinerContentEntry.getTitle())) {
stamper.getAcroFields().setField(titleFieldName,
pdfCombinerContentEntry.getTitle() + "........................" + pageNumber);
stamper.getAcroFields().setField(contentDescriptionFieldName, "");
stamper.getAcroFields().setField(pageNumberFieldName, "");
}
i++;
}
}
// determine starting page number...
// if there are contents (proposal report), it will be the total pdf pages + 1 otherwise it will be 1.
Integer startingPageNumber = pdfCombinerArguments.getContents() != null ? pdfCombinerArguments.getContents().get(0).getNumberOfPages() + 1 : 1;
// refresh page numbers starting from the max page number (this number can be > 1 if there are content entries)
pdfCombinerArguments.refreshPageNumbering(startingPageNumber);
// set AppendixTitle fields
if (pdfCombinerArguments.getAppendixes() != null) {
// set appendix
if(!pdfCombinerArguments.getAppendixes().isEmpty())
stamper.getAcroFields().setField(String.format("AppendixTitle%s", 1), "Appendix");
int i = 1;
for(PDFCombinerFile pdfCombinerFile : pdfCombinerArguments.getAppendixes()) {
if(pdfCombinerFile.isShowAppendixEntry()) {
// set appendix title
String appendixTitleFieldName = String.format("AppendixTitle%s", i + 1);
String pageTitle = pdfCombinerFile.getTitle();
if(pageTitle != null && pageTitle.contains("_bis_sheet.pdf")){
pageTitle = "BIS Sheets..........................................................................................";
}
if(pageTitle != null && pageTitle.contains("_maps.pdf")){
pageTitle = "Maps................................................................................................";
}
stamper.getAcroFields().setField(appendixTitleFieldName, pageTitle);
// set appendix page number
String appendixPageFieldName = String.format("AppendixPage%s", i + 1);
String startPageNumber = String.valueOf(pdfCombinerFile.getStartPageNumber());
stamper.getAcroFields().setField(appendixPageFieldName, startPageNumber);
// next index
i++;
}
}
}
stamper.getAcroFields().setField("versionNumber", pdfCombinerArguments.getVersionNumber());
stamper.close();
pdfTemplatePdfReader.close();
//System.out.println(tempFile.getAbsolutePath());
return tempFile.getAbsolutePath();
}
}