Generating and downloading an .xlsx file and opening it successfully
- July 12, 2022
- 2 replies
- 4802 views
Hello,
I am new to CF and I am struggling to convert an existing form that creates and downloads an .xls file
into a form that creates and downloads an .xlsx file.
We are currently running ColdFusion Server Enterprise 2021,0,03,329779.
The current main .cfm page queries the data, formats the output,
and calls another .cfm to generate the .xls file.
The struggle is after code changes are made and after the .xlsx file is created and downloaded,
I receive the error message:
"Excel cannot be open the file 'nnnnn.xlsx' because the file format or file extension is not valid"
The main.cfm page uses the following file name, header data, and formatting masks structure:
<cfsilent>
<cfscript>
variables.fileName = "#replace(reportData.headerData.reportTitle, ' ', '', 'all')#_#dateFormat(reportData.headerData.reportUpdatedDate, 'yyyymmdd')#.xls";
variables.headerContent = "#reportData.headerData.reportTitle#";
// styles
styles = StructNew();
styles.th = "border: 1px solid ##FFFFFF; background-color:##15317E; color:##FFFFFF; text-align:center; font-weight:bold;";
styles.td = "border: 1px solid black; background-color:##FFFFFF; color:##000000;";
styles.note = "background-color:##FFFFFF; color:##000000;";
styles.salesPA = "mso-number-format:'00000';";
styles.starsID = "mso-number-format:'000000000';";
styles.pct = "mso-number-format:'0\.0000%';";
styles.date = "mso-number-format:'mmmm yyyy';";
styles.head1 = "font-size:18px; font-weight:bold;";
styles.head2 = "font-size:16px; font-weight:bold;";
styles.head3 = "font-size:16px; font-weight:normal; color:red;";
styles.hr = "border-bottom: 1px solid black; background-color:##FFFFFF; color:##000000;";
variables.colSpan = reportData.headerData.numColumns;
</cfscript>
</cfsilent>The remaining code formats the output from the database query. ( Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production)
<cfsavecontent variable="variables.outputContent">
<table border="0">
<cfoutput>
<!--- report header --->
<tr>
<td colspan="#variables.colSpan#" align="center" style="#styles.head1#">
#UCase(reportData.headerData.reportTitle)#
</td>
</tr>
<!--- Overall info --->
<tr>
<td colspan="#variables.colSpan#"> </td>
</tr>
<cfif reportData.headerData.reportType eq "NATHIST">
<tr>
<td colspan="#variables.colSpan#" align="left" style="#styles.head2#">
National Report
</td>
</tr>
<cfelse>
<tr>
<td colspan="#variables.colSpan#" align="left" style="#styles.head2#">
Market Area: #reportData.headerData.hubName#
</td>
</tr>
<tr>
<td colspan="#variables.colSpan#" align="left" style="#styles.head2#">
Region: #reportData.headerData.regionName#
</td>
</tr>
</cfif>
<tr>
<td colspan="#variables.colSpan#"> </td>
</tr>
<tr>
<td colspan="#variables.colSpan#" align="left" style="#styles.head3#">
<strong>Note:</strong> In order to display on this report, dealerships must achieve #application.program.getDisplayName()# at least once.
</td>
</tr>
<tr>
<td colspan="#variables.colSpan#"> </td>
</tr>
</cfoutput>
<cfif reportData.qBodyData.recordCount eq 0>
<tr>
<cfoutput>
<td colspan="#variables.colSpan#">No records were found matching your search criteria.<br>Please try another search.</td>
</cfoutput>
</tr>
<cfelseif reportData.qBodyData.recordcount gt 65500>
<tr>
<cfoutput>
<td colspan="#variables.colSpan#">
The report has exceeded the Microsoft Excel record limitation of 65,500 records.
<br/>Please revise your reporting criteria and regenerate your report.
</td>
</cfoutput>
</tr>
<cfelse>
<cfoutput>
<!--- header row --->
<tr valign="bottom">
<cfif reportData.headerData.hubName eq "All">
<td style="#styles.th#" width="80">MARKET<br/>AREA</td>
</cfif>
<cfif reportData.headerData.regionName eq "All">
<td style="#styles.th#" width="95">#UCASE(form.rptMode)#<br/>REGION</td>
</cfif>
<td style="#styles.th#" width="55">SALES<br/>CODE</td>
<td style="#styles.th#" width="55">PARTS<br/>CODE</td>
<td style="#styles.th#" width="300">DEALER NAME</td>
<td style="#styles.th#" width="100">DEALER STATUS</td>
<cfloop query="reportData.headerData.qProgramYears">
<td style="#styles.th#" width="35">#reportData.headerData.qProgramYears.program_year#</td>
</cfloop>
<td style="#styles.th#" width="50">TOTAL<br/>COUNT</td>
</tr>
</cfoutput>
<cfoutput query="reportData.qBodyData" group="hub_name">
<cfoutput group="region_name">
<cfoutput group="sales_code">
<cfoutput group="parts_code">
<tr>
<cfif reportData.headerData.hubName eq "All">
<td style="#styles.td#">#reportData.qBodyData.hub_name#</td>
</cfif>
<cfif reportData.headerData.regionName eq "All">
<td style="#styles.td#" align="center">#reportData.qBodyData.region_name#</td>
</cfif>
<td style="#styles.td##styles.salesPA#">#reportData.qBodyData.sales_code#</td>
<td style="#styles.td##styles.salesPA#">#reportData.qBodyData.parts_code#</td>
<td style="#styles.td#">#reportData.qBodyData.dealer_name#</td>
<td style="#styles.td#">#reportData.qBodyData.dealer_status#</td>
<cfoutput>
<td style="#styles.td#" align="center">#reportData.qBodyData.winner_flag#</td>
</cfoutput>
<td style="#styles.td#" align="right">#reportData.qBodyData.total_count#</td>
</tr>
</cfoutput>
</cfoutput>
</cfoutput>
</cfoutput>
</cfif>
</table>
</cfsavecontent>The cfsavecontent is then passed to the following to generate and download the .xls file.
<common:generateExcelFile
FileName="#variables.fileName#"
FileContent="#variables.outputContent#"
PrintScale="#variables.printScale#"
HeaderContent="#variables.headerContent#"The following generates and downloads the .xls file.
<cfif thisTag.executionMode eq "start">
<cfheader name="Content-Type" value="unknown">
<cfheader name="Content-Disposition" value="attachment;filename=#attributes.FileName#">
<cfcontent type="application/msexcel">
<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns="https://www.w3.org/TR/html40/">
<body>
<cfoutput>#attributes.FileContent#</cfoutput>
</body>
</html>
</cfif>I have changed the file name to have an extension of ".xlsx" in the main.cfm and in the .cfm that generates the excel file, I modified <cfcontent type="application/msexcel"> to <cfcontent type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet">
The goal, if at all possible, is to keep the same formatting that is used now. I am aware of the various "Spreadsheet" functions but I am trying to avoid rewriting the code and having to reformat the excel file.
I have also attached a small test page to try and download an .xlsx file and it also gives the same error:
"Excel cannot be open the file 'nnnnn.xlsx' because the file format or file extension is not valid"
Please let me know what I may be missing for the xls to xlsx conversion.
