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

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 developer advocate. He focuses on JavaScript, serverless 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

Comments