我不确定我是否理解正确,但我认为如果我使用 POI Event 模型,并且在 excel 列中没有数据(只是空白,甚至没有空格),则根本不会读取数据。我遇到的问题是说我有一个有 15 列的模型,我正在读取数据以从 Excel 表中填充模型。我读取 excel 并将数据存储在列表中,然后添加到模型如果其中一列没有数据,POI 什么也不读取,因此我创建的列表只有 14 列。然后我无法匹配模型和列表中的列。
我该如何解决这个问题?
我不确定我是否理解正确,但我认为如果我使用 POI Event 模型,并且在 excel 列中没有数据(只是空白,甚至没有空格),则根本不会读取数据。我遇到的问题是说我有一个有 15 列的模型,我正在读取数据以从 Excel 表中填充模型。我读取 excel 并将数据存储在列表中,然后添加到模型如果其中一列没有数据,POI 什么也不读取,因此我创建的列表只有 14 列。然后我无法匹配模型和列表中的列。
我该如何解决这个问题?
如果您将 HSSF 用于 .xls 文件,则可以使用MissingRecordAwareHSSFListener,它会向您发送特殊记录以指示间隙。一个很好的例子是XLS2CSVmra。但是,您说您在 XSSF 上为 .xlsx,所以它有点不同
这是一个涵盖 .xlsx 文件中缺失记录的 Apache POI 示例,您需要查看XLSX2CSV 示例。基本上,您应该有一个变量来保存您看到的最后一个列号。当(单元格)startElement
触发时c
,检查参考列与最后看到的列。如果存在间隙,请在该点触发空单元格到您的逻辑,然后记录新列并处理。
获取当前列号的逻辑类似于:
// Get the cell reference
String r = attributes.getValue("r");
int firstDigit = -1;
for (int c = 0; c < r.length(); ++c) {
if (Character.isDigit(r.charAt(c))) {
firstDigit = c;
break;
}
}
thisColumn = nameToColumn(r.substring(0, firstDigit));
不要忘记在新行上重置列计数器(endElement
通常row
是触发它的好方法)
感谢@Gagravarr,给了我解决问题的初步想法。我没有按照您的建议进行操作。相反,我所做的是,我比较了列引用中的字符(ASCII 值),当前一个和最后一个。我跟踪最后一列引用并检查两列引用之间的差异是否应始终为 1,即 B1 - A1 == 1。与此的任何偏差我认为是跳过一列。该解决方案完美运行,以下是我所做的一个片段:
char currColChar = attributes.getValue("r").charAt(0);
// Check if we have missed a column due to no data
if ((currColChar - lastColumnChar) > 1) {
//logic for column skipped
}
lastColumnChar = currColChar;