Skip to content

Instantly share code, notes, and snippets.

@gregstewart
Created March 11, 2011 15:36
Show Gist options
  • Save gregstewart/866034 to your computer and use it in GitHub Desktop.
Save gregstewart/866034 to your computer and use it in GitHub Desktop.
Function to merge an array of PDF documents into one and another function to stamp a PDF document onto another
<cffunction name="mergePDFs" access="public" output="false" returntype="binary" hint="">
<cfargument name="pdfs" type="array" required="true" />
<cfset var document = "" />
<!--- // temp PDF file to be written to --->
<cfset var fileOut = ExpandPath("./" & createUUID() & ".pdf") />
<cfset var fileIO = "" />
<cfset var writer = "" />
<cfset var cb = "" />
<cfset var pdf = 0 />
<cfset var byteArrayInputStream = "" />
<cfset var pdfReader = "" />
<cfset var page = "" />
<cfset var i = 0 />
<cfset var binaryPdf = "" />
<!--- // create and initialised the document --->
<cfset document = CreateObject("java", "com.lowagie.text.Document") />
<cfset document.init() />
<!--- //output stream - to file sadly --->
<cfset fileIO = CreateObject("java", "java.io.FileOutputStream") />
<cfset fileIO.init(fileOut) />
<!--- // writer --->
<cfset writer = CreateObject("java", "com.lowagie.text.pdf.PdfWriter") />
<cfset writer = writer.getInstance(document, fileIO) />
<!--- // ok let's start open the document --->
<cfset document.open() />
<!--- // get the content --->
<cfset cb = writer.getDirectContent() />
<!--- //now loop over the generated pdfs --->
<cfloop from="1" to="#ArrayLen(pdfs)#" index="pdf">
<!--- //push the pdfs into an input stream --->
<cfset byteArrayInputStream = createobject("java", "java.io.ByteArrayInputStream").init(pdfs[pdf]) />
<!--- // create a pdf reader for the generated pdf --->
<cfset pdfReader = createObject("java", "com.lowagie.text.pdf.PdfReader").init(byteArrayInputStream) />
<!--- // figure out haw many pages are in the loaded document and then add them one at a time to our merged PDF --->
<cfloop from="1" to="#pdfReader.getNumberOfPages()#" index="i">
<cfset document.newPage() /><!--- // self explanatory add a new page to our document --->
<cfset page = writer.getImportedPage(pdfReader, javaCast("int", i)) /><!--- // get the current page to merge in --->
<cfset cb.addTemplate(page, 0, 0) /><!--- // add it to our document. --->
</cfloop>
</cfloop>
<!--- // once done close the document and the output stream --->
<cfset document.close() />
<cfset fileIO.close() />
<!---
// couldn't an output byte array stream to work, so let's cludge and read the file into binary
// so we can delete the physical file
// and then return the result to the browser
--->
<cffile action="readBinary" file="#fileOut#" variable="binaryPdf">
<cftry>
<cffile action="delete" file="#fileOut#" />
<cfcatch></cfcatch>
</cftry>
<cfreturn binaryPdf />
</cffunction>
<cffunction name="stampPdf" access="public" output="false" returntype="binary" hint="function to stamp a pdf document onto all pages onto the base pdf document passed in.">
<cfargument name="baseDocument" type="binary" required="true" />
<cfargument name="stampDocument" type="binary" required="true" />
<cfargument name="x" type="numeric" required="true" />
<cfargument name="y" type="numeric" required="true" />
<cfset var document = "" />
<!--- // temp PDF file to be written to --->
<cfset var fileOut = ExpandPath("./" & createUUID() & "_stamper.pdf") />
<cfset var fileIO = "" />
<cfset var writer = "" />
<cfset var cb = "" />
<cfset var basePDFByteArray = "" />
<cfset var pdfReader = "" />
<cfset var stamper = "" />
<cfset var stampPDFByteArray = "" />
<cfset var stamperReader = "" />
<cfset var noOfPages = 0 />
<cfset var i = 0 />
<cfset var binaryPdf = "" />
<!--- // create and initialised the document --->
<cfset document = CreateObject("java", "com.lowagie.text.Document") />
<cfset document.init() />
<!--- //output stream - to file sadly --->
<cfset fileIO = CreateObject("java", "java.io.FileOutputStream") />
<cfset fileIO.init(fileOut) />
<!--- // writer --->
<cfset writer = CreateObject("java", "com.lowagie.text.pdf.PdfWriter") />
<cfset writer = writer.getInstance(document, fileIO) />
<!--- // ok let's start open the document --->
<cfset document.open() />
<!--- // get the content --->
<cfset cb = writer.getDirectContent() />
<!--- //push the pdfs into an input stream --->
<cfset basePDFByteArray = createobject("java", "java.io.ByteArrayInputStream").init(arguments.baseDocument) />
<cfset pdfReader = createObject("java", "com.lowagie.text.pdf.PdfReader").init(basePDFByteArray) />
<cfset stamper = createObject("java", "com.lowagie.text.pdf.PdfStamper").init(pdfReader, fileIO) />
<cfset stampPDFByteArray = createobject("java", "java.io.ByteArrayInputStream").init(arguments.stampDocument) />
<cfset stamperReader = createObject("java", "com.lowagie.text.pdf.PdfReader").init(stampPDFByteArray) />
<cfset noOfPages = pdfReader.getNumberOfPages() />
<cfset stamperReader = stamper.getImportedPage(stamperReader, 1) />
<cfloop index="i" from="1" to="#noOfPages#">
<cfset cb = stamper.getOverContent(javaCast("int", i)) />
<cfset cb.addTemplate(stamperReader, arguments.x, arguments.y) />
</cfloop>
<cfset stamper.close() />
<cfset fileIO.close() />
<cffile action="readBinary" file="#fileOut#" variable="binaryPdf">
<cftry>
<cffile action="delete" file="#fileOut#" />
<cfcatch></cfcatch>
</cftry>
<cfreturn binaryPdf />
</cffunction>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment