ColdFusion:如何生成电子表格而不将其另存为文件?

在ColdFusion应用程序中,我需要使用户可以将电子表格保存到硬盘上。

我已经能够通过将它们构build为XML或HTML表格,应用application/vnd.ms-excel MIMEtypes,并以.xls扩展名保存它们,从而即时生成文件。

 <cfheader name="Content-Disposition" value="attachment; filename=MySpreadsheet.xls"> <cfcontent type="application/vnd.ms-excel"> 

但是,当用户加载这样一个文件,他们总是会得到一个恼人的消息(由于Excel的扩展强化function ):

您尝试打开的文件“_____。xls”与文件扩展名指定的格式不同。 打开文件之前,validation该文件是否已损坏并且来自受信任的来源。 你想现在打开文件吗?

我宁愿避免这个消息。

我知道<cfspreadsheet>标记和SpreadsheetWrite()函数将生成一个不显示此消息的正确的Excel文件,但它们都需要一个参数来指示服务器上的文件将被写入的位置。 由于下载可能包含敏感信息,而且一旦将文件写入服务器后,我不能轻松执行安全性,因此我不想创build这样的文件 – 即使是暂时的。 (我知道我可以提供一个密码,但是这并不是一个理想的解决scheme,在生成Excel文件之后的业务stream程中)。

我怎样才能生成Excel文件,并提示下载没有先写入文件?

在为这个问题淘了Stack Overflow和其他资源之后,我终于在另一个问题的上下文中find了解决scheme。 我现在在这里发布这个问题和我的发现,希望其他人能够比我更容易地find这些信息。

解决scheme围绕着SpreadsheetReadBinary()函数和<cfcontent>标记中的variable属性。

我使用ColdFusion电子表格函数构build了一个电子表格 ,然后在文件末尾放置以下内容(与我在开始时放入<cfheader><cfcontent>习惯相反)。

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

如果有人会从更多的细节中受益, .cfm文件中的以下内容将构build电子表格并提示下载为正确形成的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 )#">