无法使用ColdFusion

时间:2016-05-24 15:58:44

标签: excel coldfusion coldfusion-10 cfspreadsheet

我收到客户要求从查询中生成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表格上没有收到此类警告。

1 个答案:

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