Coldfusion 使用标记流式传输Excel数据会导致Excel文件损坏
我正在尝试以下方式发送excel数据Coldfusion 使用标记流式传输Excel数据会导致Excel文件损坏,coldfusion,coldfusion-9,coldfusion-10,coldfusion-8,Coldfusion,Coldfusion 9,Coldfusion 10,Coldfusion 8,我正在尝试以下方式发送excel数据 <cfsavecontent variable="xlsOutput"> //My data </cfsavecontent> <cfsetting enablecfoutputonly="no" showDebugOutput="false"> <cfheader name="ContentDisposition value='attachment;filename="#xls_file#.xls"'>
<cfsavecontent variable="xlsOutput">
//My data
</cfsavecontent>
<cfsetting enablecfoutputonly="no" showDebugOutput="false">
<cfheader name="ContentDisposition value='attachment;filename="#xls_file#.xls"'>
<cfcontent type="application/vnd.ms-excel" reset="true" variable="#ToBinary( ToBase64(xlsOutput) )#">
虽然附件以excel格式显示得很好,但当我试图打开它时,它抛出了以下错误
文件已损坏,无法打开
出现此错误消息后,文件刚刚关闭,甚至没有显示其内容
我知道我已经很接近了,但我不确定我哪里弄错了?很久以前,我们使用下面的技术实现了这一点。现在我来看看cfspreadsheet标签 我们所做的是:首先将变量保存到htm文件,然后使用excel打开它。它仍然会向用户提出一个看起来不太好看的问题:您试图打开的文件的格式与扩展名指定的格式不同,等等。。。。下面是解决方案
<cfsavecontent variable="xlsOutput">
//My data
</cfsavecontent>
<cffile action="WRITE" file="D:\wwwroot\yourwebsite\test.htm" output="#ToBinary( ToBase64(xlsOutput) )#">
<cfheader name="Content-Type" value="xls">
<cfheader name="Content-Disposition" value="attachment; filename=report.xls">
<cfcontent type="application/vnd.ms-excel" file="D:\wwwroot\yourwebsite\test.htm" deletefile="No">
我想你的托比纳里和多巴哥可能会碍事 下面是一个使用cfspreadsheet、spreadsheetAddColumn和SpreadsheetAddRows的工作示例
<!--- FILE --->
<cfset myFile = expandPath('accountslog_#dateFormat(url.datefrom, 'yyyy-mm-dd')#_#dateFormat(dateAdd('d',1,url.dateto), 'yyyy-mm-dd')#.xls') />
<cfset thisSheet = SpreadsheetNew("accountLog") />
<cfquery name="all">
SELECT
accountlog.dateTime
, accounts.firstname
, accounts.lastname
, accounts.email
, ... more columns
FROM accountlog INNER JOIN accounts on accountlog.accountid = accounts.id
WHERE dateTime
BETWEEN <cfqueryparam value="#url.dateFrom#" cfsqltype="cf_sql_timestamp">
AND <cfqueryparam value="#dateAdd('d',1,url.dateTo)#" cfsqltype="cf_sql_timestamp">
<cfif url.accountid neq ''>
AND accounts.id = <cfqueryparam value="#url.accountid#" cfsqltype="cf_sql_varchar">
</cfif>
ORDER BY datetime
</cfquery>
<cfset thisTable = 'accountLog'>
<cfset thisSheet = SpreadsheetNew( thisTable ) />
<!--- COLUMN HEADERS, droooool --->
<cfloop array="#all.getMetaData().getColumnLabels()#" index="c">
<cfset spreadsheetAddColumn(thisSheet, c) />
</cfloop>
<!--- ADD THE DATA --->
<cfset SpreadsheetAddRows(thisSheet, all) />
<!--- SAVE THE SHEET --->
<cfspreadsheet
action="update"
filename="#myFile#"
name="thisSheet"
sheetname="#thisTable#" />
<cfheader name="Content-Disposition" value="attachment; filename=#listLast(myFile, '\')#" />
<cfcontent type="application/msexcel" reset="yes" file="#myFile#" deleteFile="yes" />
它仍然会给用户一个问题。。。用另一条错误消息替换一条错误消息并不是真正的解决方案;-增强的安全功能使得Excel的新版本对旧把戏的容忍度大大降低——浏览器认为html是一个电子表格把戏。唯一可靠的解决方案是生成一个真实的电子表格。我同意,这是一个变通办法,不太适合商业应用。我不相信CF在cfspreadsheet标签之前与Excel配合得很好。。。此外,在我的示例中生成的文件实际上会在提示后由excel打开,而不是问题中的致命错误。这取决于版本。有些人仍然会有问题。旧的html技巧曾经是一个可行的选择。不幸的是,随着新版本的容忍度越来越低,它越来越可能导致错误或可怕的警告,这不是一种愉快的用户体验。总之,你的第一个建议是更好的选择,即创建一个真正的电子表格。编辑不是讽刺,但你在发布之前是否搜索过该错误消息?关于该错误的常见原因,有很多线程。通常与Excel安全设置相关。此外,如果这是实际代码,则cfheader是一个结束引号,并且header名称中有一个输入错误。Hi Leigh。。是的,我在论坛上查过各种其他相关问题,但从来没有找到正确的问题。如果你能看到一些相关的东西,请告诉我这个特定的问题,你可以自由地关闭这个线程。我只需要一个正确的答案来回答我真正的问题,不要多也不要少:当生成一个临时文件时,一定要使用唯一的文件名。否则,该文件可能会被同时运行的另一个线程覆盖。保留显示名称的日期戳逻辑,但使用一些唯一的东西,如物理文件的createUUID。此外,如果您只是编写一次性文件,请使用SpreadSheetWrite或。根据我的经验,这里无论如何都不需要。