Coldfusion 使用标记流式传输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"'>

我正在尝试以下方式发送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格式显示得很好,但当我试图打开它时,它抛出了以下错误

文件已损坏,无法打开

出现此错误消息后,文件刚刚关闭,甚至没有显示其内容


我知道我已经很接近了,但我不确定我哪里弄错了?

很久以前,我们使用下面的技术实现了这一点。现在我来看看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或。根据我的经验,这里无论如何都不需要。