使用<cfcontent>标记流式传输Excel数据会导致Excel文件损坏

时间:2016-09-16 20:29:15

标签: 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"'>

<cfcontent type="application/vnd.ms-excel" reset="true" variable="#ToBinary( ToBase64(xlsOutput) )#">

虽然附件在excel格式中很好用,但当我尝试打开它时会抛出以下错误

  

文件已损坏,无法打开

发出此错误消息后,文件才会关闭,甚至不显示其内容。

我知道我是如此接近,但我不确定我在哪里弄错了?

2 个答案:

答案 0 :(得分:1)

我认为你的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" />

答案 1 :(得分:-2)

回过头来,我们使用以下技术实现了这一点。现在我来看看 cfspreadsheet 标签。

这是我们做的:首先将变量保存到htm文件,然后使用excel打开它。它仍会向用户提出一个不太好看的问题:&#34;您尝试打开的文件采用不同的格式,由扩展名等指定...&#34;。以下是解决方案......

<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">