ColdFusion:如何生成电子表格而无需将其保存为文件?

8
在ColdFusion应用程序中,我需要让用户将电子表格保存到他们的硬盘上。
我已经能够通过构建XML或HTML表格,并应用“application/vnd.ms-excel” MIME类型,以及使用“.xls”扩展名来实时生成文件。
<cfheader name="Content-Disposition" value="attachment; filename=MySpreadsheet.xls"> 
<cfcontent type="application/vnd.ms-excel"> 

但是,当用户加载这样的文件时,他们总是会收到一个烦人的消息(由于Excel的扩展硬化功能):

您正在尝试打开的文件“_____.xls”与文件扩展名指定的格式不同。在打开文件之前,请验证该文件未损坏并来自可信任的来源。您现在要打开该文件吗?

我希望避免这个消息。
我了解 <cfspreadsheet> 标签和 SpreadsheetWrite() 函数将生成一个正确的 Excel 文件,不显示此消息 - 但它们都需要一个参数,指示服务器上要写入文件的位置。因为下载可能包含敏感信息,并且因为一旦文件被写入服务器,我就无法轻松地强制执行安全性,所以我不想创建这样的文件 - 即使是暂时的。(我知道我可以提供密码,但在生成 Excel 文件后将用于业务流程的上下文中,这不是理想的解决方案。)
如何生成 Excel 文件并提示下载,而不必先将其写入文件?
1个回答

11

在浏览 Stack Overflow 和其他资源寻找解决方案后,我终于在另一个问题的上下文中找到了解决方案。现在我将在这里发布问题和我的发现,希望其他人能比我更容易地找到这些信息。

解决方案围绕 SpreadsheetReadBinary() 函数和 <cfcontent> 标签中的 变量 属性展开。

我使用 ColdFusion 电子表格函数 创建了一个电子表格,然后将以下内容放在文件的末尾(与我通常将<cfheader><cfcontent>放在文件开头的习惯相反)。

<cfheader name="Content-Disposition" value="attachment; filename=MySpreadsheet.xls"> 
<cfcontent type="application/vnd.ms-excel" variable="#SpreadsheetReadBinary( objSpreadsheet )#">

如果需要更多细节,以下内容在.cfm文件中将构建电子表格并提示以正确格式下载Excel文件:

<!---
Building a spreadsheet that looks like:

+-----+-----+-----+
| FOO | BAR | BAZ |
+-----+-----+-----+
| 101 | 102 | 103 |
+-----+-----+-----+
| 201 | 202 | 203 |
+-----+-----+-----+

--->


<!--- Create a new spreadsheet. --->
<cfset objSpreadsheet = SpreadsheetNew()>

<!--- Create and format the header row. --->
<cfset SpreadsheetAddRow( objSpreadsheet, "FOO,BAR,BAZ" )>
<cfset SpreadsheetFormatRow( objSpreadsheet, {bold=TRUE, alignment="center"}, 1 )>

<!--- Populate the spreadsheet. --->
<!--- In a real situation, this would be looped programmatically; it is done cell-by-cell here for readability. --->
<cfset SpreadsheetSetCellValue( objSpreadsheet, 101, 2, 1, "NUMERIC" ) >
<cfset SpreadsheetSetCellValue( objSpreadsheet, 102, 2, 2, "NUMERIC" ) >
<cfset SpreadsheetSetCellValue( objSpreadsheet, 103, 2, 3, "NUMERIC" ) >
<cfset SpreadsheetSetCellValue( objSpreadsheet, 201, 3, 1, "NUMERIC" ) >
<cfset SpreadsheetSetCellValue( objSpreadsheet, 202, 3, 2, "NUMERIC" ) >
<cfset SpreadsheetSetCellValue( objSpreadsheet, 203, 3, 3, "NUMERIC" ) >

<cfheader name="Content-Disposition" value="attachment; filename=MySpreadsheet.xls"> 
<cfcontent type="application/vnd.ms-excel" variable="#SpreadsheetReadBinary( objSpreadsheet )#"> 

非常有帮助,感谢您提出这个问题并提供解决方案! - Ken Stuart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接