在ColdFusion 11中,我使用cfSpreadsheet将.xls文件转换为查询对象。下面是我的演示电子表格的屏幕截图:

创建查询对象后,我将使用以下代码查看该查询对象:
<cfspreadsheet action="read" src="demo_spreadsheet.xls"
excludeHeaderRow="true"
headerrow="1" query="demo_query"/>
<cfdump var="#demo_query#">..。我得到了这些结果:

注意,电子表格中的所有4位数的年份现在都是2位数的年份了吗?当我使用以下代码输出查询对象中的数据时:
<ul>
<cfoutput query="demo_query">
<li>#name# - #dateformat(start_date, 'medium')#</li>
</cfoutput>
</ul>..。我得到了以下输出(好的,我是新来的,所以我不能发布超过两个屏幕截图,所以您必须在这个拷贝/粘贴上信任我):
1907年是2007年,1917年是2017年,1929年是2029年,2030年是1930年。看来,1930年1月1日前的任何日期的年份为20 31,2029年12月31日之后的年份为19 31。
我是不是遗漏了什么?我以为我们在Y2K身上发现了这样的事情。是否有一个简单的设置,我有错?我在谷歌上搜索了这个问题,但我找不到任何关于它的信息。
任何建议都是非常欢迎的。
发布于 2016-01-19 18:54:01
很可能您的电子表格单元正在使用内置的*m/d/yy,这意味着显示的值(或者在本例中“读取”)可能会根据使用的环境或客户端的不同而有所不同。
以星号(*)开头的日期和时间格式响应控制面板中指定的区域日期和时间设置的更改。没有星号的格式不受“控制面板”设置的影响。
这似乎就是cfspreadsheet正在发生的情况。不确定为什么Excel显示格式*m/d/yy的年份为四位数,而不是两位数。但是,CF/POI将根据Excel规范返回正确的结果。注意,如果您将单元格格式切换为非区域性的、四位数的年份( m/d/yyyy ),则输出与您预期的一样:


更新:关于为什么CF代码显示与您预期不同的年份,这是因为CF处理日期字符串的方式不明确。需要注意的是,CFSpreadsheet返回的查询包含字符串,而不是日期对象。当您将这些字符串传递到DateFormat时,CF必须首先解释这些字符串并将它们转换为日期对象,然后才能应用日期掩码。根据CF的规则,两位数年份的解释如下:
包含根据美国语言环境约定格式化的日期/时间值的字符串。可以表示在100 AD -9999 AD范围内的日期/时间。0-29年被解释为2000-2029年;30-99年被解释为1930-1999年.
老实说,CFSpreadsheet的设计目的是提供一种简单的方式来读取和编写电子表格,而不需要太多的花哨。AFAIK,它不支持更改单元格值的解释方式。如果要强制使用四位数的年份,则必须更改电子表格以手动或编程方式使用非区域性日期格式(即使用CF读取电子表格,并应用新的单元格格式)。这可能是最简单的选择。
如果您希望在代码方面具有更大的灵活性,也可以使用电子表格功能而不是cfspreadsheet。虽然在这种具体情况下,我认为它们也缺乏必要的特点。因此,您可能会考虑使用底层POI库和一些java代码。这个帖子演示了如何获取有关电子表格单元格和值的各种详细信息。可以很容易地修改它以构建您自己的查询或包含值、格式等的结构数组:

代码:
<cfscript>
// get the sheet you want to read
cfSheet = SpreadSheetRead("c:/temp/demo_spreadsheet.xls");
workbook = cfSheet.getWorkBook();
sheetIndex = workbook.getActiveSheetIndex();
sheet = workbook.getSheetAt( sheetIndex );
// utility used to distinguish between dates and numbers
dateUtil = createObject("java", "org.apache.poi.ss.usermodel.DateUtil");
// process the rows and columns
rows = sheet.rowIterator();
while (rows.hasNext()) {
currentRow = rows.next();
data = {};
cells = currentRow.cellIterator();
while (cells.hasNext()) {
currentCell = cells.next();
col = {};
col.value = "";
col.type = "";
col.column = currentCell.getColumnIndex()+ 1;
col.row = currentCell.getRowIndex()+ 1;
col.format = currentCell.getCellStyle().getDataFormatString();
if (currentCell.getCellType() EQ currentCell.CELL_TYPE_STRING) {
col.value = currentCell.getRichStringCellValue().getString();
col.type = "string";
}
else if (currentCell.getCellType() EQ currentCell.CELL_TYPE_NUMERIC) {
if (DateUtil.isCellDateFormatted(currentCell)) {
col.value = currentCell.getDateCellValue();
col.type = "date";
}
else {
col.value = currentCell.getNumericCellValue();
col.type = "number";
}
}
else if (currentCell.getCellType() EQ currentCell.CELL_TYPE_BOOLEAN) {
col.value = currentCell.getBooleanCellValue();
col.type = "boolean";
}
// ... handle other types CELL_TYPE_BLANK, CELL_TYPE_ERROR, CELL_TYPE_FORMULA
data["COL"& col.column] = col;
}
// this row is finished. display all values
WriteDump(data);
}
</cfscript>https://stackoverflow.com/questions/34882005
复制相似问题