I have a query that gets data for a sales report for a group of stores.
I need to create a PDF of the monthly sales for each store and then email the sales manager the report for his/her store only.
The create PDF part is working fine. It creates a separate report for each store.
When I try to email the report, it sends one report for each record instead of one report for all sales people. EX: If there are 4 people on the report for store #1, the sales manager will get 4 reports instead on 1 report.
Here is my code: Creating the PDF
<cfoutput query="data" group="site_name">
<cfdocument format="pdf" overwrite="yes" fontembed="yes"
pagetype="Letter"
filename="xxxxxxxxxxxxxxxsite_name#.pdf" margintop="0.25"
marginbottom="0.25" marginleft="0.25" marginright="0.25"
backgroundvisible="yes">
<table width="100%" align="center" border="1" cellpadding="5"
cellspacing="0">
<tr bgcolor="##e1e8f7">
<td colspan="8" align="center">Sales Report -#today#-#site_name#</td>
</tr>
<tr align="center">
<td>Sales Person</td>
<td>Total Sales</td>
</tr>
<cfoutput>
<tr>
<td>#firstName# #lastName#</td>
<td>#totalSales#</td>
</tr>
</cfoutput>
</table>
</cfdocument>
</cfoutput>
CFMAIL
<cfmail query="data" to="#salesmanageremail#" subject="monthly sales
report"
type="html">
<style type="text/css">
body { font-size: 12px; font-family: Arial; }
</style>
<body>
Report attached.
</body>
<cfsilent>
<cfmailparam file="xxxxxxxxxxxxxxxsite_name#.pdf">
</cfsilent>
</cfmail>
How do I email one report per store containing all of the data to each sales manager?
You can treat your cfmail tag as a cfoutput tag. That includes using the group attribute as you did when creating the pdf.
Alternatively, you can put the cfmail tag within the cfoutput block you are using to create the pdf. All things considered, that's the approach I would take. That way you send the correct file for each site.
Related
I am trying to get some assistance with wkhtmltopdf.
I have downloaded and installed and trying to get it to work correctly with my program.
What I have is a form that lets the user choose print, preview or excel. When the user chooses print I want pop up the html table that is created by a query depending on the associates and locations that are chosen.
Right now when the user chooses print it just shows this table in the browser.
<cfif FORM.Format IS "print">
<!---<cfdocument format="pdf" scale="75" backgroundvisible="yes" overwrite="no" fontembed="yes">--->
<link rel="stylesheet" href="css/form-table.css"/>
<!---<cfdocumentitem type="header" >
<cfoutput><p align= "right">Page #cfdocument.currentpagenumber# of #cfdocument.totalpagecount#</p></cfoutput>
</cfdocumentitem> --->
<div class="RTable">
<h3 class="RTable-h3">CHECKLIST STATS</h3>
<cfoutput>
<ul class="RTable-headingList">
<li>FROM <span class="RTable-headingList-date">#dateFormat(date1, 'mm/dd/yyyy')#</span> TO <span class="RTable-headingList-date">#dateFormat(date2, 'mm/dd/yyyy')#</span></li>
<li>LOCATIONS: <span class="RTable-headingList-locations">#locList#</span></li>
</ul>
</cfoutput>
<table class="table table-hover RTable-table">
<thead>
<tr>
<th>Associate Name</th>
<th>Location</th>
<th><small>Generated by</small>Associate</th>
<th><small>Generated by</small>Selected Location(s)</th>
<th><small>Associate Percentage of</small>Location Total</th>
</tr>
</thead>
<tbody>
<cfoutput query="GetEmployeeInfo">
<tr>
<td class="RTable-name"><cfif rnA EQ 1><strong>#assoc_name#</strong></cfif></td>
<td class="RTable-location"><cfif rnL EQ 1>#trans_location#</cfif></td>
<td>#checklistsByAssocLoc#</td>
<td>#assocChecklistsByLoc#</td>
<td>#DecimalFormat(totalChecklistsByAssocLocPct)# %</td>
<!---<td> rnA: #rnA# | rnL: #rnL# | rnTotAssoc: #rnTotAssoc# </td> --->
</tr>
<cfif rnTotAssoc EQ 1>
<tr class="RTable-row-associate-total">
<td>Associate Total</td>
<td></td>
<td>#totalChecklistsByAssoc#</td>
<td>#totalAssocChecklistsByAllFilteredLoc#</td>
<td>#DecimalFormat(totalChecklistsByLocPct)# %</td>
</tr>
</cfif>
</cfoutput>
</tbody>
</table>
</div>
<!---</cfdocument>--->
I am trying to use it like cfdocument in the <cfif FORM.Format IS "print"> do I cfexecute this table some how in replace of how I have the table? I am using this as reports and dont want to save a million reports to the server. I guess I am looking for some assistance in getting off on the right foot. Any help would be greatly appreciated.
Iv tried adding this code inside the if "print":
<cfexecute name="C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe"
arguments="http://path/path/checklist/wkhtmltestpage.cfm C:\temp\wkhtmlTest.pdf"
errorVariable="errorMessage"
timeout="10"
/>
But this does not download it to show the user to print.
Also for some reason its not going to the link I am specifying its making a pdf of the login page...
When WKHTMLTOPDF requests the webpage, the "user" is not authenticated and the CGI.Http_User_Agent contains "wkhtmltopdf". The remote IP of the request will also be a local IP that is configured on the server. As a result, I don't directly process any CFM scripts using WKHTMLTOPDF.
I recommend:
Use CFContent to capture generated static HTML.
Save the HTML to a public-accessible directory with a random file name.
Use the web path + random file name w/WKHTMLTOPDF command line.
After PDF is generated, delete random files.
This process will make any issues easier to troubleshoot. I prefer creating static BAT files with the same randomized filename so that I can manually re-run on the server or even locally on my on PC to further troubleshoot and view any weird messages returned by the program. There's many other command line settings you'll want to pass (margins, orientation, pagesize, header/footer, JS delay, etc), so creating a standalone BAT file with all of the command line arguments is the best approach. (I noticed in another question that you may be using CFX_Exec. I recommend using it over CFExecute.)
<!--- Simple WKHTMLTOPDF Generation Usage --->
<cfset FileID = CreateUUID()>
<cffile action="WRITE" file="#webroot#\#FileID#.htm" output="#TheHTML#">
<cfexecute name="C:\wkhtmltopdf.exe" arguments="http://mywebsite.com/#FileID#.htm C:\temp\#FileID#.pdf" timeout="30">
<cffile action="DELETE" file="#webroot#\#FileID#.htm">
To deliver the PDF file, you can either perform a 302 redirect to the randomized PDF file and let your webserver handle the mimetype (and then delete it later) or use CFContent to deliver it using a ColdFusion thread and automatically delete it:
<!--- Return PDF to browser inline or as downloadable attachment --->
<!--- <cfheader name="content-disposition" value="attachment; filename=""NiceFilename.pdf"""> --->
<cfheader name="content-disposition" value="inline; filename=""NiceFilename.pdf""">
<cfcontent type="application/pdf" file="C:\temp\#FileID#.pdf" deletefile="Yes">
I am working with Coldfusion10 and am facing this error:
The following information is meant for the website developer for debugging purposes.
Error Occurred While Processing Request
cfdocument tag has no body.
It must have a body or a source file or URL.
I checked the website and detected that cfsettings is not defined at the top or anywhere which can cause this issue, I am using it as
<cfdocument format="pdf">
<cfdocumentsection>
<cfdocumentitem type="header"></cfdocumentitem> - Footer is used too
</cfdocumentsection>
I tried using evalAtPrint= true but still no success. Am I missing something here?
Make sure you are actually putting in at the end. I'm assuming you just missed this here.
Otherwise everything seems to align up with the Wiki Docs.
I would suggest two things.
Verify you are using ColdFusion 11 Update 3. Update 3 was a major update and may have addressed this issue.
If you are using update 3, open a bug at bugbase.adobe.com
The error message you included in your question indicates that there is no content between your <cfdocument> tags. The code that you included corroborates that. If this is not your actual code then we cannot be of much help.
You need to include the content that you would like to be converted into PDF between the <cfdocument> tags. You need something like this:
<cfquery datasource="cfdocexamples" name="empSalary">
SELECT Emp_ID, firstname, lastname, e.dept_id, salary, d.dept_name
FROM employee e, departmt d
WHERE e.dept_id = d.dept_id
ORDER BY d.dept_name
</cfquery>
<cfdocument format="PDF">
<cfoutput query="empSalary" group="dept_id">
<cfdocumentsection>
<cfdocumentitem type="header">
<font size="-3"><i>Salary Report</i></font>
</cfdocumentitem>
<cfdocumentitem type="footer">
<font size="-3">Page #cfdocument.currentpagenumber#</font>
</cfdocumentitem>
<h2>#dept_name#</h2>
<table width="95%" border="2" cellspacing="2" cellpadding="2" >
<tr>
<th>Employee</th>
<th>Salary</th>
</tr>
<cfset deptTotal = 0 >
<!--- inner cfoutput --->
<cfoutput>
<tr>
<td>
<font size="-1">#empSalary.lastname#, #empSalary.firstname#</font>
</td>
<td align="right">
<font size="-1">#DollarFormat(empSalary.salary)#</font>
</td>
</tr>
<cfset deptTotal = deptTotal + empSalary.salary>
</cfoutput>
<tr>
<td align="right"><font size="-1">Total</font></td>
<td align="right"><font size="-1">#DollarFormat(deptTotal)#</font></td>
</tr>
<cfset deptTotal = 0>
</table>
</cfdocumentsection>
</cfoutput>
</cfdocument>
Copied from the ColdFusion documentation here
I want to send a email using a href="mailto.."
I have this working code below:
<cfset month = URL.Month>
<cfset year = URL.Year>
<cfquery datasource="newsletters" name="testing">
SELECT * FROM departments_names
where dates >='#datestart#' and dates < #dateend#
AND shooting_star_dept_name IS NOT NULL
ORDER BY
DATEPART(year, dates),
DATEPART(month, dates),
</cfquery>
<cfoutput query="testing" GROUP="deptartmetn_name">
<tr>
<td>
<a href="mailto:?subject=#month#/#year#%20%20Results%20for%20newsletters&
body=#total_count#%20#total/total_count#">
Send email to #deptartmetn_name#</a></td>
</tr>
</cfoutput>
Which just send a simple "12/2" (for example).
I would like to be able to send more than just simple text.
I would like when i click on a link to be able to send a table like below:
<table>
<thead>
<tr >
<th> First Name</th>
<th> Last Name</th>
<th>total</th>
</tr>
</thead>
<cfoutput query="testing">
<tbody>
<tr >
<td>#employee_name#</td>
<td>#employee_lastname#</td>
<td>#total_count#</td>
</tr>
</tbody>
</cfoutput>
</table>
I would like to see what I'm sending first to the recipient.
Would something like this be possible or is there a better way to do this?
My first post here and beginner to coding.
You could use an AJAX callback on your links and use cfmail with cfsavecontent (for the actual HTML content/body of the message) in your callback handler code.
I use cftable or cfloop to output a table of items in ColdFusion. But what is the right way to call the editor page on clicking one of table rows?
Here is the code:
<table class="grid">
<tr>
<th>id</th>
<th>Date</th>
<th>Description</th>
<th>Status</th>
<th>Urgency</th>
<th>Severity</th>
</tr>
<cfloop query="GetIssues">
<tr>
<td><cfoutput>#id#</cfoutput></td>
<td><cfoutput>#CreatedOn#</cfoutput></td>
<td><cfoutput>#ShortDesc#</cfoutput></td>
<td><cfoutput>#Status#</cfoutput></td>
<td><cfoutput>#Urgency#</cfoutput></td>
<td><cfoutput>#Severity#</cfoutput></td>
</tr>
</cfloop>
</table>
I could use a href to make GET request to editor page, but is it the right/safe way?
You can certainly create a link to the editor page and pass the ID, however, if your IDs are numeric, it will be easy for nefarious users to guess the ID of another item. To mitigate this issue, I tend to use UUIDs for my IDs. It is extremely difficult to guess at the ID of another element.
Also, it is better to wrap the cfloop in a cfoutput, rather than wrapping each td - and you should scope your variable names.
For example:
<cfoutput>
<cfloop query="GetIssues">
<tr>
<td>#GetIssues.id#</td>
<td>#GetIssues.CreatedOn#></td>
<td>#GetIssues.ShortDesc#</td>
<td>#GetIssues.Status#</cfoutput></td>
<td>#GetIssues.Urgency#</cfoutput></td>
<td>#GetIssues.Severity#</td>
</tr>
</cfloop>
</cfoutput>
I am creating a Word format .doc using the following code, then cfheader and cfcontent to serve. All is good but I need to be able to place dynamic information in the header (or footer), or automatic pagenumbering would be a second best option.
How should I modify the code?
<cfsavecontent variable="myDocument">
<html xmlns:w="urn:schemas-microsoft-com:office:word">
<!--- Head tag instructs Word to start up a certain way, specifically in
print view. --->
<head>
<xml>
<w:WordDocument>
<w:View>Print</w:View>
<w:SpellingState>Clean</w:SpellingState>
<w:GrammarState>Clean</w:GrammarState>
<w:Compatibility>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
</w:Compatibility>
<w:DoNotOptimizeForBrowser/>
</w:WordDocument>
</xml>
</head>
<body>
Regular HTML document goes here
<!--- Create a page break microsoft style (took hours to find this)
--->
<br clear="all"
style="page-break-before:always;mso-break-type:page-break" />
Next page goes here
</body>
</html>
</cfsavecontent>
Please have a look at this: Header & Footer
I have successfully created custom header and footer with only one html file using this article. (Word 2003)
Hope this helps!
Doesn't seem easy to add page number using a WordprocessingML
http://openxmldeveloper.org/archive/2006/08/03/443.aspx
If you can serve PDF instead of DOC, here's a solution for page numbering.
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7c21.html
See example 2:
<cfdocument format="pdf">
<cfdocumentitem type="header" evalatprint="true">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td align="right"><cfoutput>#cfdocument.currentsectionpagenumber# of
#cfdocument.totalsectionpagecount#</cfoutput></td></tr>
</table>
</cfdocumentitem>
<cfdocumentitem type="footer" evalatprint="true">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td align="center"><cfoutput>#cfdocument.currentpagenumber# of
#cfdocument.totalpagecount#</cfoutput></td></tr>
</table>
</cfdocumentitem>
...
</cfdocument>