10 Replies Latest reply on Nov 16, 2006 8:58 PM by cf_dev2

    Concatenating PDF files

    fords75
      I'm looking to dump two PDF files to the browser from Coldfusion concatentated into 1 PDF file. Each file is one page long. Does anyone know if this is possible?

      Using two cfcontent tags? Is this allowed? I've tried this and it only ends up displaying the first file -

      <cfcontent type="application/pdf"
      file = "#filePath1#"
      deleteFile = "no">
      <cfcontent type="application/pdf"
      file = "#filePath2#"
      deleteFile = "no">

      Thanks in advance.
      Scott
        • 1. Re: Concatenating PDF files
          Level 7
          yes they can. PaulH posted this a while back. Maybe it'll help...

          <cfscript>
          listOfPDFs="test.pdf,test.pdf,test.pdf"; // list of PDFs to concatenate
          finalOutPutFile="concatenatedPDF.pdf"; // new output file
          // setup needed objects
          pdfCopy=createObject("java", "com.lowagie.text.pdf.PdfCopy");
          pdfReader=createObject("java","com.lowagie.text.pdf.PdfReader");
          pageSize=createObject("java", "com.lowagie.text.PageSize").init();
          bookMark=createObject("java","com.lowagie.text.pdf.SimpleBookmark");
          pdfDocument=createObject("java","com.lowagie.text.Document");
          // setup new PDF

          newPDF=createObject("java","java.io.FileOutputStream").init(expandPath(finalOut
          PutFile));
          // grab existing PDFs
          pageOffset=0;
          PDFs=listToArray(listOfPDFs); //pdfs to copy
          master=arrayNew(1); //master list
          for (i=1; i LTE arrayLen(PDFs); i=i+1) {
          reader=""; // clobber reader
          pdfFile=expandPath(PDFs );
          reader=pdfReader.init(pdfFile);
          reader.consolidateNamedDestinations();
          pages=reader.getNumberOfPages(); // number of pages in this PDF
          bookmarks=bookMark.getBookmark(reader);
          if (isDefined("bookmarks")) {
          if (pageOffset NEQ 0)
          bookMark.shiftPageNumbers(bookmarks, pageOffset, javacast("null",""));
          arrayAppend(master,bookmarks);
          } // if has bookmarks
          pageOffset=pageOffset+pages;
          if (i EQ 1) {
          pdfDocument.init(reader.getPageSizeWithRotation(1));
          pdfCopy.init(pdfDocument, newPDF);
          pdfDocument.open();
          } // first file in list?
          // now add pages to new PDF
          for (p=1; p LTE pages; p=p+1){
          page=pdfCopy.getImportedPage(reader,javacast("int",p));
          pdfCopy.addPage(page);
          }// loop pages in this PDF
          // special case: does this thing have any forms?
          acroForm=reader.getAcroForm();
          if (isDefined("acroForm"))
          pdfCopy.copyAcroForm(reader);
          } //loop PDFs
          if (arraylen(master) GT 0)
          pdfCopy.setOutlines(master);
          pdfDocument.close(); //done & done
          </cfscript>

          --
          Tim Carley
          www.recfusion.com
          info@NOSPAMINGrecfusion.com
          • 2. Re: Concatenating PDF files
            mcadle Level 1
            SWEET!! I have been looking for something like this for forever. Question though, could you use this to converge two seperate CF reports (.cfr's) that generate into pdf into one pdf report?
            • 3. Re: Concatenating PDF files
              Level 7
              mcadle wrote:
              > SWEET!! I have been looking for something like this for forever. Question
              > though, could you use this to converge two seperate CF reports (.cfr's) that
              > generate into pdf into one pdf report?

              as long as the reports hit the file system as PDFs, yes. otherwise i imagine you
              could do it in cfreport (ie combine the two reports into one).
              • 4. Re: Concatenating PDF files
                fords75 Level 1
                Thanks guys - I'll try it out.
                • 5. Re: Concatenating PDF files
                  Prashantgenial
                  Hi,
                  I want to write a hello world in a pdf using "coldfusion + iText Liabrary."
                  I am able to make some of the object's BUT

                  //4. Error in the give below statement
                  PdfWriter.init(pdfDocument, newPDF);
                  this line cause error occure.

                  Please tell me How I associate my pdfDocument object with the pdfWriter object.




                  //1. create document object
                  pdfDocument=createObject("java","com.lowagie.text.Document");

                  finalOutPutFile="brochure_printer_test.pdf"; // new output file

                  // setup new PDF
                  newPDF=createObject("java","java.io.FileOutputStream").init(expandPath(finalOutPutFile));

                  pdfWriter = createObject("java","com.lowagie.text.pdf.PdfWriter");

                  //4. Error in the give below statement
                  PdfWriter.init(pdfDocument, newPDF);

                  I am Getting Following Error:
                  The system has attempted to use an undefined value, which usually indicates a programming error, either in your code or some system code.

                  Null Pointers are another name for undefined values.

                  • 6. Re: Concatenating PDF files
                    Level 7
                    Prashantgenial wrote:
                    > //4. Error in the give below statement
                    > PdfWriter.init(pdfDocument, newPDF);

                    try pdfWriter.getInstance(pdfDocument,newPDF);
                    • 7. Re: Concatenating PDF files
                      Prashantgenial Level 1
                      Hi,
                      i found the solution to my previous post .
                      since i do not initialize the pdfDocument object so this Error Occurs.
                      //initialize the pdfDocument
                      pdfDocument.init();

                      now
                      I have completed basic PDF generation Using "iText - PDF GENERATION Liabrary".
                      I think this is very helpfull .

                      <cfscript>
                      thispath = ExpandPath("*.*");
                      currDir = GetDirectoryFromPath(thispath);
                      finalOutPutFile="brochure_printer_test.pdf"; // new output file
                      //create a paragraph object.
                      paragraph = createObject("java","com.lowagie.text.Paragraph");
                      //1. create document object
                      pdfDocument=createObject("java","com.lowagie.text.Document");
                      //initialize the pdfDocument
                      pdfDocument.init();
                      //create file output stream
                      newPDF=createObject("java","java.io.FileOutputStream").init(expandPath(finalOutPutFile));
                      //2. create pdfWriter Instance
                      pdfWriter = createObject("java","com.lowagie.text.pdf.PdfWriter");
                      //associate pdfDocument with pdfWriter
                      PdfWriter.getInstance(pdfDocument, newPDF);
                      //3. open document object
                      pdfDocument.open();
                      //4. write data into pdf document goes Here ............
                      paragraph.init("Vikram Jeet.");
                      //write paragraph in the document.
                      pdfDocument.add(paragraph);

                      //5. close pdf stream
                      pdfDocument.close();
                      </cfscript>

                      Done......

                      <!--- Uncomment the given below line TO Show the Generated Pdf --->
                      <cfcontent type="application/pdf" file = "#currDir#brochure_printer_test.pdf" deleteFile = "no">
                      • 8. Re: Concatenating PDF files
                        EmmanuelRuiz
                        Our pdf form generator using itext libraries has been broken since upgrading from cfmx6.1 to cfmx7. Has anyone encountered any issues with cfmx7?

                        <cfcomponent output="false" displayName="coldPDF">

                        <cfset variables.dsn = "">

                        <cffunction name="init" access="public" returnType="coldPDF"
                        output="false">
                        <cfargument name="dsn" type="string" required="true">

                        <cfset variables.dsn = arguments.dsn>

                        <cfreturn this>
                        </cffunction>

                        <cffunction name="fillInForm" access="public" returnType="string"
                        output="false" hint="This will fill in fields from a PDF with matching
                        fields from a database.">




                        <cfargument name="sourcePDF" type="string" required="true"
                        hint="Provide a full path to output your PDF">
                        <cfargument name="query" type="query" required="true">
                        <cfargument name="destinationPDF" type="string"
                        required="false" default="">




                        <cfset var tempPDF = expandPath("#CreateUUID()#.pdf")>
                        <cfset var document = "">
                        <cfset var copy = "">
                        <cfset var fileIO = "">
                        <cfset var i = "">
                        <cfset var pages = "">
                        <cfset var pdfReader = "">
                        <cfset var pdfName = "">
                        <cfset var newPDF = "">
                        <cfset var reader = "">
                        <cfset var stamp1 = "">
                        <cfset var form1 = "">
                        <cfset var page = "">
                        <cfset var dPage = "">
                        <cfset var annots = "">
                        <cfset var ali = "">
                        <cfset var annot = "">
                        <cfset var refObj = "">
                        <cfset var an = "">
                        <cfset var tName = "">
                        <cfset var tType = "">
                        <cfif len(arguments.destinationPDF)>
                        <cfset tempPDF = expandPath(arguments.destinationPDF)>
                        </cfif>
                        <!--- Start instance of iText --->
                        <cfset pdfReader =
                        createObject("java","com.lowagie_new.text.pdf.PdfReader")>
                        <!--- Instance of document --->
                        <cfset document =
                        createObject("java","com.lowagie_new.text.Document").init()>
                        <!--- Create byte array to put document in memory --->
                        <cfset fileIO =
                        createObject("java","java.io.ByteArrayOutputStream").init()>
                        <!--- setup new PDF --->
                        <cfset newPDF =
                        createObject("java","java.io.FileOutputStream").init(tempPDF)>
                        <!--- Create new copy of document --->
                        <cfset copy =
                        createObject("java","com.lowagie_new.text.pdf.PdfCopy").init(document,ne
                        wPDF)>
                        <!--- PDFName object --->
                        <cfset pdfName =
                        createObject("java","com.lowagie_new.text.pdf.PdfName")>
                        <!--- Open document --->
                        <cfset document.open()>

                        <!--- Loop through records --->
                        <cfloop query="arguments.query">
                        <!--- Load in file --->
                        <cfset reader = pdfReader.init(arguments.sourcePDF)>
                        <!--- filling in the form --->
                        <cfset stamp1 =
                        createObject("java","com.lowagie_new.text.pdf.PdfStamper").init(reader,fileIO)>
                        <!--- Get List of fields --->
                        <cfset form1 = stamp1.getAcroFields()>
                        <!--- Loop through pages --->
                        <cfloop index="page" from="1"
                        to="#reader.getNumberOfPages()#" step="1">
                        <!--- Get current page --->
                        <cfset dPage =
                        reader.getPageN(javacast("int",page))>
                        <!--- A Name --->
                        <cfset annots =
                        reader.getPdfObject(dPage.get(pdfName.ANNOTS))>
                        <!--- Returns an ArrayList containing PdfObjects
                        --->
                        <cfset ali = annots.getArrayList()>
                        <!--- Loop through objects --->
                        <cfloop index="annot" from="1" to="#ali.size()#"
                        step="1">
                        <!--- Get pdfObject --->
                        <cfset refObj = ali[annot]>
                        <!--- Get reference --->
                        <cfset an = reader.getPdfObject(refObj)>
                        <!--- Field Name --->
                        <cfset tName = trim(an.get(PdfName.T))>
                        <!--- Field Type --->
                        <cfset tType = form1.getFieldType(tName)>
                        <!--- Text is 4 Combo is 2 --->
                        <cfswitch expression="#tType#">
                        <cfcase value="2">
                        <!--- If checkbox set to Yes
                        --->
                        <cfif
                        len(arguments.query[tName][arguments.query.currentrow])>
                        <cfset
                        form1.setField(tName, "Yes")>
                        </cfif>
                        <cfbreak>
                        </cfcase>
                        <cfcase value="4">
                        <!--- If text box input string
                        --->
                        <cfset form1.setField(tName,
                        javacast("string",arguments.query[tName][arguments.query.currentrow]))>
                        <cfbreak>
                        </cfcase>
                        </cfswitch>
                        </cfloop>
                        </cfloop>
                        <!--- <cfdump var="#form1.getFields()#">
                        <Cfabort> dump way to get all the fields from this cfc ---->
                        <!--- Flatten stamper --->
                        <cfset stamp1.setFormFlattening(true)>
                        <!--- Close stamper --->
                        <cfset stamp1.close()>

                        <!--- Read document that is in memory --->
                        <cfset reader = pdfReader.init(fileIO.toByteArray())>
                        <!--- Get number of pages --->
                        <cfset pages = reader.getNumberOfPages()>
                        <!--- Add pages to final document --->
                        <cfloop index="i" from="1"
                        to="#reader.getNumberOfPages()#" step="1">
                        <cfset
                        copy.addPage(copy.getImportedPage(reader,javacast("int",i)))>
                        </cfloop>
                        </cfloop>
                        <!--- Close document --->
                        <cfset document.close()>
                        <!--- Return path to temp file --->
                        <cfreturn tempPDF>
                        </cffunction>
                        • 9. Re: Concatenating PDF files
                          dudeatwar
                          I tried this and got the following error:
                          Complex object types cannot be converted to simple values. from this code:
                          The error occurred in C:\CFusionMX7\wwwroot\AMS\pdf.cfm: line 31

                          29 : for (i=1; i LTE arrayLen(PDFs); i=i+1) {
                          30 : reader=""; // clobber reader
                          31 : pdfFile=expandPath(PDFs);


                          Why all of a sudden am I getting this? Thanks.