流Excel中的数据会导致损坏的Excel文件
我想通过以下方式流Excel中的数据会导致损坏的Excel文件
<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格式发送Excel数据,当我试图打开它,它抛出以下错误
文件已损坏,无法打开
此错误信息后,T他甚至没有显示内容就关闭文件。
我知道我很亲密,但我不知道我在哪里得到它全部错误?
回来之前我们使用下面的技术来实现这一点。现在我会看看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">
*它仍然会给用户一个问题... *替换一个错误信息是不是一个真正的解决方案;-)增加安全功能让更新版本的Excel远远不能容忍旧的“欺骗浏览器进入思维html是电子表格”的伎俩。唯一可靠的解决方案是生成*真实*电子表格。 – Leigh
我同意,这是一个解决方法,不太适合商业应用。我不相信在cfspreadsheet标签之前CF可以很好地工作......另外,我的示例中生成的文件实际上会在提示之后由excel打开,而与问题中的致命错误相关。 –
全部取决于版本。有些人仍然会遇到问题。旧的html技巧*曾经是一个可行的选择。不幸的是,随着新版本越来越宽容,越来越可能导致错误或可怕的警告,这不是一个愉快的用户体验。底线,你的第一个建议是更好的选择,即创建一个真正的电子表格。 – Leigh
我想你的toBinary()和tobase64()可能会受到阻碍。
这是一个使用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" />
生成临时文件时,请务必使用* unique *文件名。否则,该文件可能会被另一个同时运行的线程覆盖。保持显示名称的日期戳记逻辑,但使用唯一的东西,比如'createUUID()'作为物理文件。另外,如果您只是编写一次性文件,请使用SpreadSheetWrite()或'
(编辑)不是讽刺,但你在发布之前是否对该错误消息进行搜索?有很多关于该错误常见原因的线索。通常与Excel安全设置有关。另外,如果这是实际的代码,'cfheader'很害羞,而且头文件中有一个拼写错误。 – Leigh
嗨Leigh ..是的,我在论坛上查看了其他相关的其他问题,但没有找到正确的答案。如果您能看到相关的内容,请将我引导至特定问题,并且您可以*关闭此主题。我只是需要一个正确的答案,我的真正的问题,没有更多的东西:) – Tej