I'm generating a <table> and converting it to PDF using <cfdocument>. I would like to include the table header on the new page when it runs over. This is around every 30th line.
Here is my current code. The <cfif> is supposed to force a break at every new line. However, all it seems to do is create 4 blank pages with the content at the bottom, formatted the same as it was before
<cfloop query="One">
<cfif not(One.currentrow MOD 30)>
<cfdocumentitem type="pagebreak" />
<th>Contact Name</th>
</cfif>
<cfoutput>
#One.contactName#
</cfoutput>
Fixed. Here is what I used to get my header on every page. Further note, if you need to adjust the document header size, then include margintop="2.2" in your main tag and adjust to taste.
<cfdocumentitem type="header" evalAtPrint="true" >
<td>Contact Name</td>
</cfdocumentitem>
Try This: This is the solution that i got.
<cfloop query="get_list">
<!---7 row each page--->
<cfset mode = get_list.currentrow mod 7>
<cfif mode eq 1>
<thead>
<tr>
<td>table header</td>
</tr>
</thead>
</cfif>
<tbody>
<tr>
<td>data loop here</td>
</tr>
<tr>
<td>
<cfif mode eq 0>
<cfdocumentitem type="pagebreak">
</cfdocumentitem>
</cfif>
</td>
</tr>
</tbody>
</cfloop>
</table>
Related
I have two queries and each query is outputted on the screen in separate table. Both quires have the same number of records but I would like to check if each field is equal if not I want to set different background color for that table row. Here is the code that I have so far:
<cfquery name="oldData" datasource="test">
SELECT
old_id,
old_userid,
old_first,
old_last,
old_dob
FROM OldTest
</cfquery>
<cfquery name="newData" datasource="test">
SELECT
new_id,
new_userid,
new_first,
new_last,
new_dob
FROM NewTest
</cfquery>
And here is code for both tables:
<table>
<tr>
<td valign="top">
<table class="oldData">
<caption>Old Data</caption>
<thead>
<tr>
<th>ID</th>
<th>UserID</th>
<th>First</th>
<th>Last</th>
<th>DOB</th>
<tr>
</thead>
<tbody>
<cfoutput query="oldData">
<tr>
<td>#old_id#</td>
<td>#Trim(old_userid)#</td>
<td>#Trim(old_first)#</td>
<td>#Trim(old_last)#</td>
<td>#Trim(old_dob)#</td>
</tr>
</cfoutput>
</tbody>
</table>
</td>
<td valign="top">
<table class="newData">
<caption>New Data</caption>
<thead>
<tr>
<th>ID</th>
<th>UserID</th>
<th>First</th>
<th>Last</th>
<th>DOB</th>
<tr>
</thead>
<tbody>
<cfoutput query="newData">
<tr>
<td>#new_id#</td>
<td>#Trim(new_userid)#</td>
<td>#Trim(new_first)#</td>
<td>#Trim(new_last)#</td>
<td>#Trim(new_dob)#</td>
</tr>
</cfoutput>
</tbody>
</table>
</td>
</tr>
</table>
I'm wondering if I should compare data rows before the output something like:
<cfif oldData.old_first[currentrow] NEQ newData.new_first[currentrow]>
<cfset rowColor = "red">
</cfif>
Or there is better way to approach this. If anyone knows better way please let me know.
I would use looping:
<cfloop from="1" to="#oldData.recordCount#" index="r">
Question #oldData.old_id[r]# = #oldData.new_id[r]#? Answer: #oldData.old_id[r] eq oldData.new_id[r]#<br>
</cfloop>
You can wrap the loop around TRs and TDs if you desire.
This method also eliminates the need for a QofQ, which are resource intensive.
I suggest a query of queries resembling this:
select 'same' comparison, field1, field2, etc
from query1, query2
where query1.someField = query2.someField
union
select 'different' comparison, field1, field2, etc
from query1
where somefield not in (<cfqueryparam value="#valueList(query2.someField#") list = true>
Your table row colour can be specified with a ternary operator.
<tr bgcolor="#comparison is 'same' ? 'white' : 'red'#">
I am trying to create multiple pdfs and save them to a directory. I have a query based off a Appid. For each appid i need to create a pdf and store in the location. I am able to create the pdf for one appid. When I try to create pdf for more than one appid, the data is being added to the current pdf. Below is my code. Please advice as to what is going wrong here.
<cfquery name="getdetails" datasource="#CSTTDB#" username="#CSTTUSR#" password="#CSTTPWD#">
select a.motsid,B.APP,B.ITCONTACT,B.STD,B.ED,B.DIRECTOR,a.tool,a.upddate,a.EAQUESTION from bnsit.TBLEAMGMT a,scott.tblaccessmgmt b
where A.MOTSID = b.motsid
and a.motsid = '16'
and a.recid = '28'
and a.EAQUESTION = 'Yes'
</cfquery>
<cfif getdetails.recordcount gt 0>
<cfloop query="getdetails">
<cfdocument
format="pdf"
srcfile="\\wiwauk4colddw11.itservices.sbc.com\ITUPCOMP\pdf\"
filename="#getdetails.motsid#_#dateformat(upddate,"mmddyy")#_eareport.pdf"
overwrite="yes">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Emergency Access BNSIT - #getdetails.motsid#</title>
</head>
<style type="text/css" media="print">
td{
width=50%;
}
.tpx td{
border: solid 1px black;
}
</style>
<body>
<img src="email_header_plain.jpg" align="center" border= "0" alt="Header">
<p align="center">
<font size="+2" color="navy"> <strong>EMERGENCY ACCESS BNSIT</strong></font>
</p>
<br>
<cfoutput>
<cfset timenow = dateformat(now(),'mm/dd/yyyy')>
<TABLE id="mytable" align="center" class="tpx" bgcolor="azure" border="1" width="80%">
<tr>
<tr>
<th align="left"><strong>MOTSID:</strong></th>
<th align="left">#motsid#</th>
</tr>
<tr>
<th align="left"><strong>Application Name:</strong></th>
<th align="left">#app#</th>
</tr>
<tr>
<th align="left"><strong>IT Contact:</strong></th>
<th align="left">#itcontact#</th>
</tr>
<tr>
<th align="left"><strong>STD:</strong></th>
<th align="left">#STD#</th>
</tr>
<tr>
<th align="left"><strong>Director:</strong></th>
<th align="left">#director#</th>
</tr>
<tr>
<th align="left"><strong>ED:</strong></th>
<th align="left">#ED#</th>
</tr>
<tr>
<th align="left"><strong>Access Provisioning Tool:</strong></th>
<th align="left"> </th>
</tr>
<tr>
<th align="left"><strong>Emergency Access Tool:</strong></th>
<th align="left">#tool#</th>
</tr>
<tr>
<th align="left"><strong>Confirmation Received Date:</strong></th>
<th align="left">#dateformat(upddate,"mm/dd/yyyy")#</th>
</tr>
</table>
</cfoutput>
</body>
</html>
</cfdocument>
</cfloop>
<cffile action="COPY" source="\\wiwauk4colddw11.itservices.sbc.com\ITUPCOMP\pdf\#getdetails.motsid#_#dateformat(upddate,"mmddyy")#_eareport.pdf" destination="\\135.16.235.36\devcompliance\pdfreports\">
</cfif>
EDIT: I have updated the code above, I am trying to copy the created pdf file from one location to another server. The pdf file is being create fine in the source folder with the given naming convention.
But im am getting below error at the cffile copy. any thoughts please?
This code
<cfdocument
format="pdf"
srcfile="\\wiwauk4colddw11.itservices.sbc.com\ITUPCOMP\pdf\"
filename="testpdf.pdf"
overwrite="yes">
is creating a single PDF file of the name "testpdf.pdf". The contents are created within this tag, by looping over the query content.
Instead, move your CFLOOP to outside the CFDOCUMENT tag. Now, for each record, you'll create a new PDF with the content of a single record's worth of data.
BUT, you'll also have to change the name of the file being created to be dynamic:
<cfloop query="getdetails">
<cfdocument
format="pdf"
srcfile="\\wiwauk4colddw11.itservices.sbc.com\ITUPCOMP\pdf\"
filename="testpdf_#getdetails.motsid#.pdf"
overwrite="yes">
<!--- HTML content --->
</cfdocument>
</cfloop>
This will create a new PDF file with a name unique to each motsid. Otherwise, you'll just keep re-creating a single file named "testpdf.pdf" that will ultimately have the contents of the last record from the query.
I'd like to send information to an ActionFormBean using a jsp page that contains a structured code like this:
<table>
<thead>
<tr>
<th>ID Turno</th>
<th>Data e Ora</th>
<th>Sede turno</th>
</tr>
</thead>
<tbody>
<html:form action="/dettagliTurno">
<c:forEach var="ris" items="${usersession.searchResult}" >
<tr>
<td><c:out value="${ris.idTurno}"/></td>
<td><c:out value="${ris.dataOra}"/></td>
<td><c:out value="${ris.luogo}"/></td>
<td>
<html:hidden property="id" value="${ris.idTurno}"/>
<html:submit value="Dettagli" property="id" />
</td>
</tr>
</c:forEach>
</html:form>
</tbody>
</table>
The only one information that I need to send to the ActionFormBean is "id" but if click on the button "Dettagli" of the second/third row (of the example showed in this image) the value sent to the ActionForm is always the one of the first row (that is '5')!
How can I solve this problem and set the correct value of id according to the row-button "Dettagli" selected?
GOT IT!
I solved the problem by changing code this way:
<c:forEach var="ris" items="${usersession.searchResult}" >
<tr>
**<html:form action="/dettagliTurno">**
<td><c:out value="${ris.idTurno}"/></td>
<td><c:out value="${ris.dataOra}"/></td>
<td><c:out value="${ris.luogo}"/></td>
<td>
<html:hidden property="id" value="${ris.idTurno}"/>
<html:submit value="Dettagli" property="id" />
</td>
**</html:form>**
</tr>
With this version, form set the correct value of "idTurno" and properly send it to ActionForm.
Hope it will be helpfulto someone with the same problem of mine.
Calc
When I attempt to delete an item in a shopping cart. I get a "Element Id is not defined in form" error.
Where am I going wrong?
I'm using MSSQL 2008 r2, Coldfusion 10.
Summary:
tickets.cfm this is the page that displays the products, also contains a form with hidden values to be passed on to cart_manage.cfm.
cart_manage.cfm is an action page for both tickets.cfm and cartlist.cfm
cartlist.cfm is a page that displays the shopping cart contents.
application.cfm session variables.
application.cfm
<cfapplication sessionmanagement="yes">
<cfapplication name="cart" clientmanagement="Yes"
sessionmanagement="Yes"
sessiontimeout="#CreateTimeSpan(0,0,15,0)#"
applicationtimeout="#CreateTimeSpan(0,2,0,0)#">
<cfparam name="session.allowin" default="false">
tickets.cfm
<cfif NOT IsDefined('SESSION.cart')>
<cfset SESSION.cart = ArrayNew(1) />
</cfif>
<cfquery datasource="sqltest" name="getTickets">
select *,
CASE WHEN Friday=1and Saturday=1and Sunday=1
THEN 'All three days'
WHEN Friday=0and Saturday=0and Sunday=0
THEN 'None'
ELSE
STUFF(
case when Friday=1 then ',Friday' else '' end
+ case when Saturday=1 then ',Saturday' else '' end
+ case when Sunday=1 then ',Sunday' else '' end, 1,1,'')
END WhichDays
from tickets_performances;
</cfquery>
<table width="600" border="0">
<tr>
<td>Day</td>
<td>Price</td>
<td>How Many Left</td>
<td>Quantity</td>
</tr>
<p> You can only purchase a maximum of two tickets at a time. Having a ticket limit ensures fairness to all those buying tickets. The ticket limit applies per account, billing address, and/or credit card. Please observe the ticket limit as over purchases may be cancelled without notice or warning. </p>
<cfform action="cart_manage.cfm" name="form" method="post">
<cfoutput query="getTickets">
<tr>
<td>#WhichDays#</td>
<td>£#price#</td>
<td>#stock#</td>
<td><cfinput type="text" id="quantity" name="quantity" size="5" class="field" maxlength="1" value="0"/></td>
<td><cfinput type="hidden" name="id" value="#getTickets.ticket_performanceID#" />
<cfinput type="hidden" name="item" value="#getTickets.WhichDays#" />
<cfinput type="hidden" name="price" value="#getTickets.price#" />
<cfinput type="submit" name="add_button" value="Add to Cart"></td>
</tr>
</cfoutput>
</cfform>
</table>
cart_manage.cfm
<cfset newitem = 0>
<cfloop from="1" to="#arrayLen(session.cart)#" index="i">
<cfif session.cart[i].itemid EQ #form.id#>
<cfset session.cart[i].quantity = session.cart[i].quantity + #form.quantity#>
<cfset newitem = 1>
<cfbreak>
</cfif>
</cfloop>
<cfif newitem EQ 0>
<cfset temp = arrayAppend(session.cart, structNew())>
<cfset session.cart[arrayLen(session.cart)].itemid = #form.id#>
<cfset session.cart[arrayLen(session.cart)].item = #form.item#>
<cfset session.cart[arrayLen(session.cart)].quantity = #form.quantity#>
<cfset session.cart[arrayLen(session.cart)].price = #form.price#>
<cflocation url="cartlist.cfm">
</cfif>
<cfif IsDefined('FORM.delete_button.y')>
<cfloop from="#ListLen(FORM.delete_index)#" to="1" index="i" step="-1">
<cfset ArrayDeleteAt(SESSION.cart, ListGetAt(FORM.delete_index, i))>
</cfloop>
<cflocation url="cartlist.cfm">
<cfelseif IsDefined('FORM.update_button.y')>
<cfloop from="1" to="#ArrayLen(SESSION.cart)#" index="i">
<cfset SESSION.cart[i].quantity = FORM["quantity_" & i] >
</cfloop>
<cflocation url="cartlist.cfm">
<cfelseif IsDefined('FORM.checkout_button.y')>
<cflocation url="checkout.cfm">
</cfif>
<cflocation url="cartlist.cfm">
cartlist.cfm
<cfset nTotal = 0 />
<cfform action="cart_manage.cfm" method="post">
<table width="100%">
<tr valign="top">
<td>
<table width="100%" class="white">
<tr>
<td class="tblehead"> </td>
<td class="tblehead">Item</td>
<td class="tblehead">Price Per Item</td>
<td class="tblehead">Quantity</td>
<td class="tblehead">Price</td>
</tr>
<cfoutput>
<cfloop from="1" to="#ArrayLen(SESSION.cart)#" index="i">
<tr>
<td height="40" width="40" align="center" class="dkturq">
<cfinput type="checkbox" name="delete_index" value="#i#" />
</td>
<td height="40" class="dkturq">
#SESSION.cart[i].item#
</td>
<td height="40" class="dkturq">
£#(SESSION.cart[i].price)#
</td>
<td height="40" class="dkturq">
<cfinput type="text" name="quantity_#i#" value="#SESSION.cart[i].quantity#" size="5" class="field" />
</td>
<td height="40" class="dkturq">
<cfset nPrice = SESSION.cart[i].quantity * SESSION.cart[i].price />
<cfset nTotal = nTotal + nPrice />
£#(nPrice)#
</td>
</tr>
</cfloop>
</cfoutput>
</table>
</td>
<td></td>
<td>
<table width="100%" height="100%" class="white">
<tr>
<td class="tblehead">
Summary
</td>
</tr>
<tr>
<td class="dkturq">
total:
<cfoutput>£#(nTotal)#</cfoutput>
<br /><br /><br /><br />
Clear Shopping Cart
<cfinput type="submit" name="update_button" id="update_button" value="update" />
<cfinput type="submit" name="delete_button" id="delete_button" value="delete" /><br /></a>
</td>
</tr>
</table>
</td>
</tr>
</table>
</cfform>
CFDUMP of FORM
CFDUMP of Session.cart
Error:
CFDUMP when I press delete
Thanks to Leigh, I managed to get it to work.
(Summary from the chat ..)
The original problem is pretty much what the error message said. ie Trying to use a form field that does not exist. The cause is "tickets.cfm" and "cartList.cfm" contain different form fields. The form in "cartList.cfm" does not contain a field named form.id, hence the error when that form is submitted. To avoid the error you need to verify the form.id exists, with structKeyExists() before accessing it.
However, we decided to revise the action page code instead. Also, the "cartList.cfm" form was changed to use itemID instead of index. Reason being, the index can change which might cause the wrong item to be deleted or updated. There is still room for improvement, but here is the jist of the changes:
*cartList.cfm (form fields) *
<!--- use itemID's instead of "index" in all form fields --->
<cfinput type="checkbox" name="delete_itemID" value="#SESSION.cart[i].itemid#" />
<cfinput type="text" name="quantity_#SESSION.cart[i].itemid#" value="#SESSION.cart[i].quantity#" size="5" class="field" /><br>
cartManage.cfm
<!--- ADD item to cart ---->
<cfif structKeyExists(FORM, "add_button")>
... code to add items here ...
<!--- DELETE from cart ---->
<cfelseif structKeyExists(FORM, "delete_button")>
<!---
Ensure the field exists to prevent errors. Note: A more
efficient option is to test the field's existence in the cfelseif
--->
<cfparam name="FORM.delete_itemID" default="">
<cfloop from="#ArrayLen(SESSION.cart)#" to="1" index="i" step="-1">
<!--- if this item was marked as "deleted", remove it --->
<cfif listFind(FORM.delete_itemID, SESSION.cart[i].itemID)>
<cfset arrayDeleteAt(SESSION.cart, i)>
</cfif>
</cfloop>
<!--- UPDATE item in cart ---->
<cfelseif structKeyExists(FORM, "update_button")>
<cfloop from="1" to="#ArrayLen(SESSION.cart)#" index="i">
<cfset currentItem = session.cart[i]>
<!--- Note: For safety, verify the field exists first --->
<cfset currentItem.quantity = FORM["quantity_" & currentItem.itemID] >
</cfloop>
</cfif>
I have a table on a page with data generated from a query. This makes it unpredictable how many rows will be generated.
When using cfdocument to output the page as a PDF the table is often cut in two on the page break.
Is there any easy way to include the table labels on the new page for the purpose of clarity?
I've had to work with cfdocument quite a bit and making it usable in certain situations can be a real bear.
I believe the answer to your question can be found on this page since you know how many records will be on each page (static row height):
COLDFUSION: cfdocument and forcing a pagebreak
Here are some other questions I've posted and worked through concerning cfdocument, hope they help.
scale PDF to single page
cfdocument prevent page breaks mid-row
CFDocument still cutting off the tops of text on some pages
try this approach, I have used it
<cfset amount="6" />
<cfdocument
format="pdf"
unit="cm"
pageType="A4"
filename="#path##name#.pdf">
<cfoutput>
<cfloop from="1" to="#amount#" index="i">
<cfset filename = "#name#_#i#" />
<cfimage
action="convert"
destination="#path#codes/#filename#.jpg"
source="#path#codes/#filename#.png" />
<img src="file://#path#codes/#filename#.jpg" style="width: 3.58cm; margin: 0 0.2cm 0.5cm;">
</cfloop>
</cfoutput>
Just adding some things that DON'T work (in CF10, which i think uses the same CFdoc renderer as CF8 & CF9):
adding content after the header element with css:after (CFdocument doesn't support css3)
thead { display: table-header-group; } (not supported)
using javascript within the table output to add a header row dynamically (the pdf renderer doesn't execute js)
testing #cfdocument.currentpagenumber# in the cfdocument body (that variable seems only to exist in the header and footer)
adding a in the (soundsOfTheDot answered his other question saying that this worked, but in my tests the renderer seems to close the table at the end of each page then re-open it)
adding a table in the with a test like to insert it on all pages after the first one (this almost does the job, if you can hard-code your column widths so the two tables line up and ensure there is no gap between this faux header and the actual table)
I hope that saves some hours.
My PDF happened to fit 21 rows per page, so I made sure the current row MODULO 21 equaled 0. Notice I start with a new table each page, so I put the new <table> along with only a <thead> inside the <cfif> after using the closing tags of </tbody> and </table> for the previous page's table and the pagebreak. Then I follow it with the <tbody>, and voila, it works like a charm. I also added a nice footer to the PDF just for funsies.
<cfquery name="getDeletedBarcodes" datasource="#application.dsn#">
SELECT * FROM deletedRecords
</cfquery>
<cfdocument filename="reports/DeletedBarcodes.pdf" format="PDF" overwrite="true">
<cfif getDeletedBarcodes.RecordCount NEQ 0>
<h2 align="center" style="text-decoration: underline; font-weight: bold">Deleted Barcode Records</h2>
<table class="deletedBarcodesTable" border="1" style="margin-top: 10px" rules="rows">
<thead>
<tr>
<th>Barcode</th>
<th>Building</th>
<th>Room</th>
<th>Location</th>
<th>Shelf</th>
<th>Inventoried</th>
<th>Deleter Name</th>
<th>Time Deleted</th>
<th>Reason Deleted</th>
</tr>
</thead>
<cfelse>
<p>There are no records to show that have deleted barcodes.</p>
</cfif>
<cfloop query="getDeletedBarcodes">
<cfoutput>
<cfif getDeletedBarcodes.currentRow MOD 21 EQ 0>
</tbody></table>
<cfdocumentitem type="pagebreak" />
<table class="deletedBarcodesTable" border="1" style="margin-top: 10px" rules="rows">
<thead>
<tr>
<th>Barcode</th>
<th>Building</th>
<th>Room</th>
<th>Location</th>
<th>Shelf</th>
<th>Inventoried</th>
<th>Deleter Name</th>
<th>Time Deleted</th>
<th>Reason Deleted</th>
</tr>
</thead>
<tbody>
</cfif>
<tr>
<td align="center"><cfif NOT StructKeyExists(getDeletedBarcodes, "Barcode") OR NOT len(Barcode)><strong style="color: red">N/A</strong><cfelse>#Barcode#</cfif></td>
<td align="center"><cfif NOT StructKeyExists(getDeletedBarcodes, "Building") OR NOT len(Building)><strong style="color: red">N/A</strong><cfelse>#Building#</cfif></td>
<td align="center"><cfif NOT StructKeyExists(getDeletedBarcodes, "Room") OR NOT len(Room)><strong style="color: red">N/A</strong><cfelse>#Room#</cfif></td>
<td align="center"><cfif NOT StructKeyExists(getDeletedBarcodes, "Location") OR NOT len(Location)><strong style="color: red">N/A</strong><cfelse>#Location#</cfif></td>
<td align="center"><cfif NOT StructKeyExists(getDeletedBarcodes, "Shelf") OR NOT len(Shelf)><strong style="color: red">N/A</strong><cfelse>#Shelf#</cfif></td>
<td align="center"><cfif NOT StructKeyExists(getDeletedBarcodes, "Inventoried") OR NOT len(Inventoried)><strong style="color: red">N/A</strong><cfelse>#LEFT(Inventoried, 10)#</cfif></td>
<td align="center"><cfif NOT StructKeyExists(getDeletedBarcodes, "DeleterName") OR NOT len(DeleterName)><strong style="color: red">N/A</strong><cfelse>#DeleterName#</cfif></td>
<td align="center"><cfif NOT StructKeyExists(getDeletedBarcodes, "TimeDeleted") OR NOT len(TimeDeleted)><strong style="color: red">N/A</strong><cfelse>#TimeDeleted#</cfif></td>
<td align="center"><cfif NOT StructKeyExists(getDeletedBarcodes, "ReasonDeleted") OR NOT len(ReasonDeleted)><strong style="color: red">N/A</strong><cfelse>#ReasonDeleted#</cfif></td>
</tr>
</cfoutput>
</cfloop>
<cfdocumentitem type="footer">
<cfoutput>
<div style="border-top: 5px solid black; border-top-width: 100vw">
<span style="left: 0; float: left">#DateFormat(Now(), "full")#</span>
<span style="right: 0; float: right">Page #cfdocument.currentpagenumber# of #cfdocument.totalpagecount#</span>
</div>
</cfoutput>
</cfdocumentitem>
</cfdocument>