2016-09-16 281 views
0

我想通過以下方式流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他甚至沒有顯示內容就關閉文件。

我知道我很親密,但我不知道我在哪裏得到它全部錯誤?

+0

(編輯)不是諷刺,但你在發佈之前是否對該錯誤消息進行搜索?有很多關於該錯誤常見原因的線索。通常與Excel安全設置有關。另外,如果這是實際的代碼,'cfheader'很害羞,而且頭文件中有一個拼寫錯誤。 – Leigh

+0

嗨Leigh ..是的,我在論壇上查看了其他相關的其他問題,但沒有找到正確的答案。如果您能看到相關的內容,請將我引導至特定問題,並且您可以自由關閉此主題。我只是需要一個正確的答案,我的真正的問題,沒有更多的東西:) – Tej

回答

-2

回來之前我們使用下面的技術來實現這一點。現在我會看看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"> 
+0

*它仍然會給用戶一個問題... *替換一個錯誤信息是不是一個真正的解決方案;-)增加安全功能讓更新版本的Excel遠遠不能容忍舊的「欺騙瀏覽器進入思維html是電子表格」的伎倆。唯一可靠的解決方案是生成*真實*電子表格。 – Leigh

+0

我同意,這是一個解決方法,不太適合商業應用。我不相信在cfspreadsheet標籤之前CF可以很好地工作......另外,我的示例中生成的文件實際上會在提示之後由excel打開,而與問題中的致命錯誤相關。 –

+0

全部取決於版本。有些人仍然會遇到問題。舊的html技巧*曾經是一個可行的選擇。不幸的是,隨着新版本越來越寬容,越來越可能導致錯誤或可怕的警告,這不是一個愉快的用戶體驗。底線,你的第一個建議是更好的選擇,即創建一個真正的電子表格。 – Leigh

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

生成臨時文件時,請務必使用* unique *文件名。否則,該文件可能會被另一個同時運行的線程覆蓋。保持顯示名稱的日期戳記邏輯,但使用唯一的東西,比如'createUUID()'作爲物理文件。另外,如果您只是編寫一次性文件,請使用SpreadSheetWrite()或''。根據我的經驗[''cfspreadsheet action = update' is buggy](http://stackoverflow.com/questions/15010472/spreadsheet-cell-formatting/15027832#15027832),並且這裏不需要。 – Leigh

相關問題