Using DDX and CFPDF to set the initial page for a PDF

This post is more than 2 years old.

Earlier this morning a reader asked about how to send a user a PDF that opened at a particular page. Apparently it is possible to link to a PDF and pass a URL parameter for the page you want to open to, but in his case, he was serving up the PDF via cfcontent. I thought it might be possible to do via DDX, and after searching, I found that this use case is actually documented in the ColdFusion docs, but unfortunately, the XML isn't complete and I had to struggle a bit to get it work. Here's how our docs show it:

<?xml version="1.0" encoding="UTF-8"?> <DDX xmlns="http://ns.adobe.com/DDX/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://ns.adobe.com/DDX/1.0/ coldfusion_ddx.xsd"> <PDF result="Out1" initialView="firstView"> ... <InitialViewProfile name="firstView" show="BookmarksPanel" magnification="FitPage" openToPage="2"/> ... </DDX>

Not only is that DDX not complete, it isn't right either. Here's the proper DDX:

<?xml version="1.0" encoding="UTF-8"?> <DDX xmlns="http://ns.adobe.com/DDX/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://ns.adobe.com/DDX/1.0/ coldfusion_ddx.xsd"> <InitialViewProfile name="firstView" openToPage="2"/> <PDF result="Out1" initialView="firstView"> <PDF source="In1" /> </PDF> </DDX>

Note that the InitialViewProfile tag is outside of the PDF tag block. Also note we have to specify an input field. So let's put it together in a full example:

<cfset pdfFile = "C:\Users\Raymond\Documents\My Dropbox\Misc Docs\rc120-010d-solr.pdf">

<cfsavecontent variable="ddxString"> <?xml version="1.0" encoding="UTF-8"?> <DDX xmlns="http://ns.adobe.com/DDX/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://ns.adobe.com/DDX/1.0/ coldfusion_ddx.xsd"> <InitialViewProfile name="firstView" openToPage="2"/> <PDF result="Out1" initialView="firstView"> <PDF source="In1" /> </PDF> </DDX> </cfsavecontent>

<cfset input = {"In1"=pdfFile}> <cfset output = {"Out1" = "c:\temp.pdf"}> <cfpdf ddxfile="#ddxString#" action="processddx" name="result" inputfiles="#input#" outputfiles="#output#"> <cfdump var="#result#">

If you've never seen CFPDF/DDX before, then this may be seem a bit weird, but basically, ColdFusion passes the XML as instructions to an embedded Livecycle Doohicky within ColdFusion. These instructions expect inputs and outputs (exactly what depends on the DDX being run), so we pass in an input struct and output struct. I've got hard coded values here but normally it would be dynamic.

And that's it. As I told the person in the other thread, DDX operations are binary and going to be slower than normal. You may want to consider caching this PDF so you can use it next time instead of generating it every time. (In general, any time you do file operations you probably want to store and cache the result. Disk space is cheap. S3 even cheaper.)

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Eric Davis posted on 1/18/2012 at 3:49 AM

Thanks Ray, this example works like a charm. I was wondering if its possible to use the same technique to open a pdf to a specific 'Destination' within the PDF. I've looked at the documentation, and don't see how to do this using the openToPage value. The CoverPage attribute looks like it maybe a way to open to a destination. Any ideas?

Comment 2 by Eric Davis posted on 1/18/2012 at 4:16 AM

Actually it looks like the destination can be accessed by simpy adding #destinationName to the end of the URL. This works even when the document is returned using cfcontent.

Comment 3 by Raymond Camden posted on 1/18/2012 at 4:22 AM

Glad you figured it out. My job here is done. ;)

Comment 4 by Susan Bethel posted on 1/23/2012 at 10:00 PM

Trying this out, but the DDXis not valid because the schema, coldfusion_ddx.xsd, can't be located. Am I missing something?

Comment 5 by Raymond Camden posted on 1/23/2012 at 10:05 PM

You get that error? Where? While the xsd does not exist, I'm able to run the code just fine.

Comment 6 by Susan Bethel posted on 1/23/2012 at 11:18 PM

Thanks for the response. I am a newbie so I assumed I must have missed some important detail. I created the DDX file in Visual Studio assuming since it is an xml file the editor would work out. After posting here, I re-created it in notepad and now it is working fine -- go figure!

Comment 7 by dehian posted on 4/27/2012 at 1:19 AM

Hi Ray,

Thanks for this post.
I managed to set magnification level using your sample code.
I only had a problem with the ddx which was not valid unless i wrote it all in a single line into the cfsavecontent tag.
It also doesn't work when you open the pdf in Chrome but that's a problem with Chrome, not with cf, i guess.

Comment 8 by Raymond Camden posted on 4/27/2012 at 1:21 AM

How does it fail in Chrome? I generate PDFs w/ Chrome via CF all the time. (Ok, not all the time, but I have in the past.)

Comment 9 by dehian posted on 4/30/2012 at 5:50 PM

Ok sorry it seems it was some cache issue, it opens now correctly to the specified magnification percentage.
Thanks again

Comment 10 by Paul posted on 5/16/2012 at 9:57 PM

Great post!
When I open the file created, you can open "print dialog" on pdf merged immediately? If possible, how do I change the DDX?

Comment 11 by Paul posted on 5/17/2012 at 5:52 PM

I found the solution:
<PDF result="output1">
<PDF source="doc1"/>
<PDF source="doc2"/>
<JavaScript source="js1" name="openPrintDialog"/>
</PDF>

"js1" is a file .js with this code:
this.print({
bUI: true
});

Comment 12 by Jeff posted on 7/19/2012 at 1:34 AM

I was trying to use this to override the size that the pdf is opened up as. I am creating a dynamic report that is in PDF format and I was wondering if I have to save this as a pdf and read from that or if I can pass the cfdocument pdf variable to the input structure. I'm getting errors trying to do so and don't know if is my code or the functionality.

Comment 13 by Raymond Camden posted on 7/19/2012 at 2:39 AM

It's been a while for me, but I'm pretty darn sure you have to save it to the file system first.

Comment 14 by Lisa Walker posted on 10/15/2012 at 10:38 PM

Hi Ray, follow your blogs constantly.
I'm having an error follow up on this line.
<cfset input = {"In1" = pdfFile}>

Invalid CFML construct found on line 13 at column 16.
ColdFusion was looking at the following text:
{

The CFML compiler was processing:

A cfset tag beginning on line 13, column 2.

Running cf8.0.

Comment 15 by Raymond Camden posted on 10/16/2012 at 12:38 AM

I don't remember when implicit struct notation came in, but it must have been CF9, not 8. So translate it so:

<cfset input = structNew()>
<cfset input["In1"] = pdfile>

Comment 16 by Colin G posted on 3/5/2013 at 11:57 PM

Sorry for lateness.
Paul's comment from 5-17-12 blew open automatic printing in ColdFusion for me. Something that threw me though: the "source" attribute in the JavaScript tag needs to be in the input structure you send to <cfpdf> via the "inputfiles" attribute. The struct key corresponds to the value you use for "source". Its value is the full path of the file. According to the Adobe docs, you can even use a URL.
Hope that helps someone.

Comment 17 by Samish Kumar posted on 4/29/2013 at 5:35 PM

Hi,
It seems like your above code might help me in splitting my pdf into multiple pdf files. i dont know what DDX and coldfusion is. can anybody tell me where i can start from, i mean i need assistance from scratch. i dont know if any third party software is required, so please help me out.

thanks.

Comment 18 by Raymond Camden posted on 4/29/2013 at 5:44 PM

You don't need DDX. CFPDF allows you to extract pages from a PDF. You could use that to 'split' a PDF doc.

Comment 19 by Samish Kumar posted on 4/30/2013 at 9:38 AM

Actually i want split pdf through javascript so if you can help me in this, it will be very appreciable.

Comment 20 by Raymond Camden posted on 4/30/2013 at 3:02 PM

Check out pdfjs then: http://mozilla.github.io/pd...

Comment 21 by Samish Kumar posted on 4/30/2013 at 4:19 PM

Thanx Raymond, for the link. I will have a look into that code.