我收到客户要求从查询中生成Excel电子表格的请求。我有查询踢出字段,我可以毫不费力地生成Excel文件。当客户端获取该Excel文件然后尝试操作它时,问题就出现了。
大部分麻烦来自应标记为货币或日期的字段。经过一番努力,我能够生成一个“真正的”日期字段。在此Excel之前没有正确排序日期。我可以使用下面的代码调用Excel公式。 DateValue
强制Excel将此视为真实日期字段。但是,当通过Excel操作此文件时,此操作会失败。
<cfset SpreadsheetSetCellFormula(s
,"DATEVALUE(#Chr(34)##Replacement_ETD##Chr(34)#)"
, therow
, 9)>
下一个问题是货币领域。我无法让Excel承认这些值作为货币。它总是出现定制。设置此项后,SUM
功能将无法在Excel中使用。您可以像A1+B1+C1 = TOTAL
一样单独添加字段。但是,当有200行时,这将没有用。
我能够得到另一位有类似情况的CF程序员的建议。他首先使用正确的标题生成Excel文件,并将列设置为适当的字段,如日期和货币等。
下一步是逐行填写字段,并且应正确格式化。
代码:
<cfset filename = expandPath("./reports/arrivals.xlsx")>
<cfspreadsheet action="read" src = "#filename#" name = "s" >
<cfset therow = 0>
<cfoutput query="myExcel" startrow="1">
<cfset therow = myExcel.currentrow + 1>
<cfset SpreadsheetSetCellValue(s, Incumbent, therow, 1)>
<cfset SpreadsheetSetCellValue(s, Section, therow, 2)>
<cfset SpreadsheetSetCellValue(s, Position_Number, therow, 3)>
<cfset SpreadsheetSetCellValue(s, Position_Title, therow, 4)>
<cfset SpreadsheetSetCellValue(s, Incumbent_Emplyment_Type, therow, 5)>
<cfset SpreadsheetSetCellValue(s, Incumbent_ETD, therow, 6)>
<cfset SpreadsheetSetCellValue(s, Tour_Comments, therow, 7)>
<cfset SpreadsheetSetCellValue(s, Replacement, therow, 8)>
<cfset SpreadsheetSetCellValue(s, Replacement_ETA, therow, 9)>
</cfoutput>
<cfheader name="content-disposition" value="attachment; filename=Departures_(#DateFormat(now(),'mmddyy')#).xls">
<cfcontent type="application/msexcel" variable="#spreadsheetReadBinary(s)#" reset="true">
单元格中的数据已经过适当格式化。生成此文件并将其传输给用户时,列的格式不符合预期。
是否有其他人知道此方法是否有效或者有更好的建议让CF生成适当的日期和货币字段以供Excel确认?
在RHEL 5上运行的Adobe ColdFusion v10。
这里的每个请求是一些使用queryNe
w的代码,它将生成代码日期和货币。
第一步:我创建了一个Excel文件,第一行被冻结,它有列标题。第一列被指定为格式为长日期的日期 - mm / dd / yyy;第二列是美元,已设为货币。
我读取该文件,然后填写行并将文件流式传输给用户下载。
<cfset filename = expandPath("./reports/Test.xlsx")>
<cfspreadsheet action="read" src = "#filename#" name = "s" >
<cfset myQuery = QueryNew("MyDate, Dollar", "Date, Decimal")>
<cfset newRow = QueryAddRow(MyQuery, 5)>
<cfset temp = QuerySetCell(myQuery, "MyDate", "03-11-2000", 1)>
<cfset temp = QuerySetCell(myQuery, "Dollar", "403.45", 1)>
<cfset temp = QuerySetCell(myQuery, "MyDate", "01-01-2009", 2)>
<cfset temp = QuerySetCell(myQuery, "Dollar", "603.22", 2)>
<cfset temp = QuerySetCell(myQuery, "MyDate", "09-21-2013", 3)>
<cfset temp = QuerySetCell(myQuery, "Dollar", "103.55", 3)>
<cfset temp = QuerySetCell(myQuery, "MyDate", "01-15-2005", 4)>
<cfset temp = QuerySetCell(myQuery, "Dollar", "3.33", 4)>
<cfset temp = QuerySetCell(myQuery, "MyDate", "07-22-2003", 5)>
<cfset temp = QuerySetCell(myQuery, "Dollar", "13.75", 5)>
<cfset therow = 0>
<cfoutput query="myQuery" startrow="1">
<cfset therow = myQuery.currentrow + 1>
<cfset SpreadsheetSetCellValue(s, DateFormat(MyDate, 'mm/dd/yyyy'), therow, 1)>
<cfset SpreadsheetSetCellValue(s, Dollar, therow, 2)>
#myQuery.currentrow# <br>
#myQuery.MyDate# <br>
#myQuery.Dollar# <br>
</cfoutput>
<cfheader name="content-disposition" value="attachment;
filename=Departures_(#DateFormat(now(),'mmddyy')#).xls">
<cfcontent type="application/msexcel" variable="#spreadsheetReadBinary(s)#" reset="true">
您可以在MS Excel或Google表格中打开该文件。测试一,第一行冻结,我们应该能够对日期字段进行排序。我的结果是:日期没有正确排序。在第2列的货币,如果我们尝试做一个工作的SUM!这之前没有用,但现在已经有效了。
此外,当我尝试打开文件时,我收到警告,指出此文件已损坏,Excel将尝试打开它。我在Google表格上没有收到此类警告。
答案 0 :(得分:0)
使用日期单元格时,CF可能有点古怪。当手动输入值时,Excel非常适合猜测正确的单元格类型。然而,CF有点棘手。由于CF是相对无类型的,因此它并不总是正确地匹配值和单元格类型。使用利用查询对象而不是SpreadsheetSetCellValue()的函数通常会产生更好的结果。最有可能的原因是查询对象包含两个值和数据类型。虽然从CF11开始,SpreadsheetSetCellValue支持新的数据参数,它允许您指定值和单元格数据类型。由于您使用的是CF10,请尝试使用SpreadsheetAddRows来填充值。
关于文件损坏的警告,这是由于下载代码中的实际文件内容和文件扩展名不匹配。代码正在读取 .xlsx 文件,但下载声称它是。 xls (application / msexcel)文件。要摆脱错误,请确保两者匹配。
以下是使用CF11测试的工作示例
<!---
Test.xlsx contains two columns, with headers on row 1
- Column A format: *m/d/yyyy
- Column B format: number with 2 decimal places
--->
<cfspreadsheet action="read" src="c:/temp/Test.xlsx" name="sheet" >
<cfset myQuery = QueryNew("")>
<cfset QueryAddColumn(MyQuery, "Dollar", "Decimal", [ 403.45, 703.22, 103.55, 3.33, 13.75] )>
<cfset QueryAddColumn(MyQuery, "MyDate", "date", [ parseDateTime("2000-03-11", "yyyy-mm-dd")
, parseDateTime("2009-01-01", "yyyy-mm-dd")
, parseDateTime("2013-09-21", "yyyy-mm-dd")
, parseDateTime("2005-01-15", "yyyy-mm-dd")
, parseDateTime("2003-07-22", "yyyy-mm-dd")] ) >
<cfset spreadsheetAddRows(sheet, myQuery)>
<cfset spreadsheetFormatColumn(sheet, {dataFormat="m/d/yy"}, 1)>
<cfset spreadsheetFormatColumn(sheet, {dataFormat="##,####0.00"}, 2)>
<cfheader name="content-disposition" value="attachment; filename=Departures_(#DateFormat(now(),'mmddyy')#).xlsx">
<cfcontent type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" variable="#spreadsheetReadBinary(sheet)#" reset="true">