Cfdocumentitem pagebreak during loop gives extra blank page - coldfusion

I am using CF9, and ColdBox. What I am doing is looping through a query, and assigning a page break at the end using cfdocumentitem pagebreak. However, it always gives me an extra blank page at the end. It's pretty much driving me crazy, so I defer to expert advice.
<cfdocument format="PDF" overwrite="Yes" localUrl="yes" pageType = "letter">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body>
<cfquery name="Receipts" dbtype="query">
SELECT distinct id_number
FROM rc.RC1
</cfquery>
<cfoutput>
<cfloop query="Receipts">
<!--- removed for brevity --->
<cfdocumentitem type="pagebreak" />
</cfloop>
</cfoutput>
</body>
</html>
</cfdocument>

If you don't want to display the pagebreak after the last item in the loop then you have to explicitly say that. If the current row of the query is not the last row in the query then display the page break.
<cfloop query="Receipts">
<cfif Receipts.currentRow NEQ Receipts.recordCount>
<cfdocumentitem type="pagebreak" />
</cfif>
</cfloop>

Related

ColdFusion - CFDOCUMENT Title in URL

I am creating a PDF document using ColdFusion cfdocument tag. Works fine, however instead of showing the document name in browser Title - it shows the .cfc file that I call to create the PDF.
Here is how I'm calling it.
<cfdocument format="pdf" marginbottom=".5" margintop=".25" marginright=".5" marginleft=".5" saveAsName="#filename#.pdf">
<cfdocumentitem type="footer">
<p style="font-size:11px; text-align:right; font-style:italic;">Page #cfdocument.currentpagenumber# of #cfdocument.totalpagecount#</p>
</cfdocumentitem>
<html>
<head><title>#filename#.pdf</title></head>
<body><img src="file:///#application.tempFolder#\#thisFilename#" /></body>
</html>
</cfdocument>
What the heck am I missing? Why does it still show the filename.cfc file that I'm calling in the browser title instead of the filename I give to the PDF???
Figured it out. Had to create the document using CFDOCUMENT, then add a "Title" attribute to it using the CFPDF tag. Then output it to the browser.
<!--- Create the PDF --->
<cfdocument format="pdf" marginbottom=".5" margintop=".25" marginright=".5" marginleft=".5" filename="#application.tempFolder#\#thisSaveAsFilename#" overwrite="yes">
<cfdocumentitem type="footer">
<p style="font-size:11px; text-align:right; font-style:italic;">Page #cfdocument.currentpagenumber# of #cfdocument.totalpagecount#</p>
</cfdocumentitem>
<html>
<head><title>#thisSaveAsFilename#</title></head>
<body><img src="file:///#application.tempFolder#\#thisFilename#" /></body>
</html>
</cfdocument>
<!--- Use CFPDF to add attributes to it --->
<cfset thisInfo = StructNew()>
<cfset thisInfo.Title = "pdf title goes here...">
<cfpdf action="setinfo" info="#thisInfo#" source="#application.tempFolder#\#thisSaveAsFilename#" />
<!--- Send it to the browser --->
<cfcontent file="#application.tempFolder#\#thisSaveAsFilename#" type="application/pdf" />A

Coldfusion Word Document Table - Keep With Next

I am building a report that outputs the information into a word document using Coldfusion. Some of the information is output into tables and occasionally the table is occurring at the bottom of a page and the table ends up breaking apart to two pages. How do I keep the table from breaking apart?
The format is .doc.
<cfsavecontent variable="myDocument">
<html xmlns:w="urn:schemas-microsoft-com:office:word">
<head>
<xml>
<w:WordDocument>
<w:View>Print</w:View>
<w:Zoom>100</w:Zoom>
<w:DoNotOptimizeForBrowser/>
</w:WordDocument>
</xml>
</head>
<body>
<!--- run some queries to get information --->
<!--- Display some information via normal <cfoutput> --->
<!--- Then display information in table like this --->
<cfset xtest_count = 0>
<cfloop query="test">
<cfif xtest_count eq 0>
<cfset xtest_count = xtest_count + 1>
<b><u>Speaker<cfif test.recordcount gt 1>s</cfif></u></b><br><br>
<table width="100%" cellpadding=3 cellspacing=2 border=1>
<tr>
<td><b>Title</b></td>
<td><b>Name</b></td>
<td><b>Credentials</b></td>
<td><b>Organization</b></td>
</tr>
</cfif>
<tr>
<td>#test.title#</td>
<td nowrap>#test.first_name# #test.last_name#</td>
<td>#test.credentials#</td>
<td>#test.company_name#</td>
</tr>
</cfloop>
</table>
<!--- Display More information--->
</body>
</html>
</cfsavecontent>

ColdFusion PDF "Open with" or "save file" prompt

How can I create a pop up that allows the user to "open with" or to save file as when dealing with coldfusion pdf's?
I am trying to figure out how to create it when this form is not actually mine and I am just using and prefilling a form that already exists.
<cfpdfform source="82040.pdf" action="populate">
<cfpdfformparam name="cust ##" value=""> <!---Section1 Customer Number--->
</cfpdfform>
I was able to create this pop up by doing something like this:
<cfsetting enablecfoutputonly="true">
<cfcontent type="application/pdf">
<cfheader name="Content-Disposition" value="attachment;filename=test.pdf">
<cfdocument format="PDF" localurl="yes"
marginTop=".25" marginLeft=".25" marginRight=".25" marginBottom=".25"
pageType="custom" pageWidth="8.5" pageHeight="10.2">
<cfoutput><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>PDF Export Example</title>
</head>
<body>
</body>
</html>
</cfoutput>
</cfdocument>
But am not sure how I can combine these two. Any help is greatly appreciated!
Per Request What I have tried:
<cfset tempFilePath = "c:/path/to/someUniqueFileName.pdf">
<cfpdfform source="82040.pdf" action="populate" destination="#tempFilePath#">
<cfpdfformparam name="org" value="Yes"> <!---Above Section1 Original ---> <!---On--->
</cfpdfform>
<cfheader name="Content-Disposition" value="attachment;filename=Testme.pdf">
<cfcontent type="application/pdf" file="#tempFilePath#" deleteFile="false">
By default, cfpdfform renders the result in the browser ie "inline". To return it as an attachment instead, save the content to a file or a variable. Then use cfheader/cfcontent to return it as an attachment.
File:
Use the "destination" attribute to save it to a file. To avoid conflicts with other threads be sure use unique file names. To automatically remove the temporary file when finished, set deleteFile="true"
<cfset tempFilePath = "c:/path/to/someUniqueFileName.pdf">
<cfpdfform source="82040.pdf" action="populate" destination="#tempFilePath#">
...
<cfheader name="Content-Disposition" value="attachment;filename=test.pdf">
<cfcontent type="application/pdf" file="#tempFilePath#" deleteFile="false">
Variable:
Use the "name" attribute to save the content to a variable. Though "name" is not listed in the documentation, this bug report suggests it is just a documentation error.
<cfpdfform source="82040.pdf" action="populate" name="pdfContent">
... etcetera ...
<cfheader name="Content-Disposition" value="attachment;filename=test.pdf">
<cfcontent type="application/pdf" variable="#toBinary(pdfContent)#">

creating dynamic drop down menu in ColdFusion

I am trying to create a dynamic database-driven drop down menu in a ColdFusion page.
I have written ul and li tags in a cfoutput tag, but nothing is displaying in the page.
<cfset dbsource="ndev9">
<cfset dbschema="security">
<cfset dbuserid="security">
<cfset dbpw="sec">
<html>
<link rel="stylesheet" href="menubar_new.css">
<link rel="stylesheet" href="bannerstyle.css">
<cfquery name="main_menu" datasource="#dbsource#" username="#dbuserid#" password="#dbpw#">
select * from #dbschema#.main_menu order by MAIN_MENU_ORDER
</cfquery>
<body>
<cfoutput>
<ul id="menu_new">
<cfloop query="main_menu">
<li>#main_menu.main_menu_name#</li>
</cfloop>
</ul>
</cfoutput>
</body>
</html>

cfdocument prevent page breaks mid-row

I know this has been asked before but the solutions are from 2.5+ years ago so I'm asking if anyone has devised or knows of a more elegant solution to the problem using CF9. Can anyone confirm if CF10 supports the "page-break-inside: avoid" rule?
How can I prevent page-break in CFDocument from occuring in middle of content?
COLDFUSION: cfdocument and forcing a pagebreak
This is pretty much how I'm doing it. I've estimated, depending on what type of page it is, I can fit 9 or 11 rows of data before having to force a page break. Of course this is prone to breaking so if anyone knows of any evolution of the solution I would be grateful.
I believe I have found a pseudo solution. It is basically just what I said in the comments above. I take a best guess and see if it fits using the value of cfpdf's getInfo.totalPages. If it fits, great, merge it to the final document, if it doesn't, try again with one less row.
The downside to doing it this way is that it slows it down a bit and you can't use some of the stuff cfdocument makes easy like like messing with headers and footers. That being said, part 2 of this solution may be to record the number of rows that fit on a page in an array instead of merging the pages and rebuild the entire document again using cfdocument and those values as the loop constraints forcing a page break after. As it is, the below solution is already a little time consuming so building it again inside of a cfdocument tag may not work in high traffic sites.
Bug workaround: It looks like there is a bug with cfdocument that removes the background colors when saving the document to memory with the name attribute. The workaround is to remove the cfdocument tag to an external file. I saw one programmer placed it into a cfc, I found it's possible to use a simple cfinclude.
I hope someone finds this helpful, and if you know a better way to do this please comment.
<cfset reviewText = "Lorem ipsum dolor sit amet, + lots of characters.">
<cfset estimatedRowsPerPage = 7> <!--- This is the max number of records you want to try on each page. The larger the gap between max and actual will slow down the process. Used to reset attemptedRowsPerPage if the value changes --->
<cfset attemptedRowsPerPage = estimatedRowsPerPage> <!---- number of rows attempted to add to the page --->
<cfset totalRowsOutput = 0><!--- this is the number of records successfully saved to the final PDF --->
<cfset recordCount = 20> <!--- this is the query's record count --->
<!--- cfpdf cannot create a file from scratch and cfdocument requires some content so a container object cannot be created without at least one page. This page will be deleted later --->
<cfdocument format="pdf" marginbottom=".25" margintop=".25" marginleft=".25" marginright=".25" name = "finalDocument">Delete me</cfdocument>
<cfloop condition="totalRowsOutput lt recordCount">
<!--- create what *should* be a single page document --->
<cfdocument format="pdf" marginbottom=".25" margintop=".25" marginleft=".25" marginright=".25" name = "testDocument">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>A title</title>
</head>
<body>
<table border="1">
<tr>
<td>Row:</td>
<td>Title:</td>
<td>Author:</td>
<td>Price:</td>
<td>Average Rating:</td>
<td>Reviews:</td>
</tr>
<cfoutput>
<cfloop from = "1" to = "#attemptedRowsPerPage#" index = "i">
<tr>
<td>
#i#
</td>
<td nowrap="nowrap">
#mid(reviewText,1,randRange(4,10))#
</td>
<td nowrap="nowrap">
#mid(reviewText,20,randRange(8,20))#
</td>
<td>
$10.00
</td>
<td>
#randRange(1,5)#
</td>
<td>
#mid(reviewText,1,randRange(10,700))#
</td>
</tr>
</cfloop>
</cfoutput>
</table>
</body>
</html>
</cfdocument>
<!--- get the document info to see if the page count = 1 --->
<cfpdf action="getinfo" source="testDocument" name="testInfo">
<cfif testInfo.totalPages gt 1>
<!--- if the page count is greater than 1 we need to try again with one less record. --->
<cfset attemptedRowsPerPage -= 1>
<cfelse>
<!--- merge the new single page to the final document --->
<cfpdf action = "merge" name = "finalDocument">
<cfpdfparam source="finalDocument">
<cfpdfparam source="testDocument">
</cfpdf>
<cfset totalRowsOutput += attemptedRowsPerPage>
<!--- if the page count = 1, we need to increment the startAttempt and reset the attemptedRowsPerPage unless attemptedRowsPerPage = recordCount --->
<cfif totalRowsOutput lt recordCount>
<!--- don't try to output more than exist --->
<cfset attemptedRowsPerPage = estimatedRowsPerPage+totalRowsOutput lt recordCount ? estimatedRowsPerPage : recordCount-totalRowsOutput>
</cfif>
</cfif>
</cfloop>
<!--- delete the manditory page needed to create our final document --->
<cfpdf action="deletePages" pages="1" source="finalDocument" name="finalDocument">
<!--- see "http://www.raymondcamden.com/index.cfm/2007/7/12/ColdFusion-8-Working-with-PDFs--A-Problem" to see why you need toBinary --->
<cfcontent type="application/pdf" variable="#toBinary(finalDocument)#">
Travis - I don't know of another way to do this. Usually I create an HTML table as the core of each "page" and have a specific number of rows before I close the table, break the page and open a new table.