tags:

views:

39

answers:

1

Is there a simple way to scale the pdf created by cfdocument or cfpdf to a single page using CF8? My output (a calendar) could possibly extend to page 2 depending on the number of events. I'd rather scale the calendar to fit it in one page. I assume I can create the pdf with cfdocument. Use cfpdf to check the page numbers and loop while totalPages > 1 create the PDF with a lesser scale.

psudo code:

pdfScale = 100
cfdocument scale = "#pdfScale#"
cfpdf action = "getinfo" name = "mypdf" 
cfloop while mypdf.totalPages > 1
pdfScale = pdfScale -5
cfdocument scale = "#pdfScale#"
cfpdf action = "getinfo" name = "mypdf"
/cfloop

Am I on the right track or am I missing something to make this easier? Thanks.

+4  A: 

Your theory seems sound to me - you should try it and find out. Since that's a rather boring answer, I've also converted your pseudocode to real code:

<cfset pdfScale = 100 />
<cfset pdfObj = "" />
<cfdocument format="pdf" name="pdfObj" scale="#pdfScale#">document contents</cfdocument>
<cfpdf action="getInfo" source="#pdfObj#" name="pdfInfo" />
<cfloop condition = "pdfInfo.TotalPages gt 1">
    <cfset pdfScale -= 5 />
    <cfdocument format="pdf" name="pdfObj" scale="#pdfScale#">document contents</cfdocument>
    <cfpdf action="getInfo" source="#pdfObj#" name="pdfInfo" />
</cfloop>

Depending on your setup, you might also want to abstract the creation of the PDF into a function, so that you don't have to re-write all of the content twice on the page. Or you could use an include. Heck, if there is any sort of complex processing going on to render the HTML for the PDF (which I assume there is, since you're making a calendar), then you might even want to pre-render the content and re-use it, like so:

<cfsavecontent variable="docContents">document contents go here</cfsavecontent>
<cfset pdfScale = 100 />
<cfset pdfObj = "" />
<cfdocument format="pdf" name="pdfObj" scale="#pdfScale#"><cfoutput>#docContents#</cfoutput></cfdocument>
<cfpdf action="getInfo" source="#pdfObj#" name="pdfInfo" />
<cfloop condition = "pdfInfo.TotalPages gt 1">
    <cfset pdfScale -= 5 />
    <cfdocument format="pdf" name="pdfObj" scale="#pdfScale#"><cfoutput>#docContents#</cfoutput></cfdocument>
    <cfpdf action="getInfo" source="pdfObj" name="pdfInfo" />
</cfloop>
Adam Tuttle
Thanks Adam. I was considering making it a cfc and adding it to cflib.org. Maybe someone else will find it helpful too. I'll be sure to credit your efforts if I do. Thanks again!
Travis
Adam, it works. took it down to 60% and I only needed to make a few changes to you untested yet accurate code. 1. `<cfoutput>` inside the cfdocument tag. 2. source = "pdfObj" instead of source = "#pdfObj#" 3. I needed to do another cfdocument outside of the loop to serve the pdf to the browser instead of putting it in memory. I'll UDF it and share later. Time for the weekend.
Travis
Travis, I updated my second code sample to reflect the changes from your comments. I would use CFContent to serve the resulting PDF to the user instead of CFDocument, though.
Adam Tuttle