我正在开发一个功能,我必须存储通过上传 Excel 文件收到的数字。它是用 Java 编写的,使用 apache poi 库,在 Spring 框架下(这是不相关的)。
我尝试上传的文件(请注意,该列已设置为文本):
代码如下:
// function accepts "MultipartFile inputFile"
InputStream is = inputFile.getInputStream();
StreamingReader reader = StreamingReader.builder().rowCacheSize(100).bufferSize(4096).sheetIndex(0)
.read(is);
for (Row row : reader) {
System.out.println("Reading next row.");
System.out.println("row[0] is of type " + row.getCell(0).getCellType());
Cell cell = row.getCell(0);
String value = "";
if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
value = cell.getStringCellValue().replaceAll("[\\D]", "");
} else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
value = NumberToTextConverter.toText(cell.getNumericCellValue());
}
System.out.println("Value is " + value);
}
我得到的输出如下:
Reading next row.
row[0] is of type 0 // Which is equals to Cell.CELL_TYPE_NUMERIC
Value is 166609999
问题是我需要将其读取为“0166609999”而不是“166609999”,奇怪的是,如果我将其保存为 xls 格式并重新上传,这种情况只会发生在 xlsx 文件上文件,我在检测其细胞类型方面没有问题。有什么想法吗?
已编辑以标记为重复:
- 给定答案 https://stackoverflow.com/a/19401902/1131470使用 DataFormatter 类,当我们流式传输工作表时不支持该类,因为检索到的 Cell 对象将是 StreamingCell 对象,如果我们调用 getCellStyle() 函数,则会抛出异常。
截至 2016 年 3 月 29 日
似乎该类StreamingCell不支持 DataFormatter,其中 DataFormatter 是目前唯一可用于获取 Excel 显示内容的类。因此,当前的解决方案是坚持将整个 Excel 文件读入内存。如果将来有人找到答案,您可以在这里发布答案,我将不胜感激,因为当前的解决方案绝对是糟糕的。
截至 2016 年 3 月 31 日
特别感谢Axel指出其库版本问题,将streamer jar文件更新到0.2.12解决了问题。谢谢!
最佳答案
已下载您的文件。下载了xlsx-streamer-0.2.12.jar
、slf4j-api-1.7.20.jar
和slf4j-nop-1.7.20.jar
> 并放置在类路径中。
有以下代码:
import com.monitorjbl.xlsx.*;
import org.apache.poi.ss.usermodel.*;
import java.io.*;
class StreamingReaderTest {
public static void main(String[] args) throws Exception {
try (
InputStream is = new FileInputStream(new File("/home/axel/Downloads/test_formatted_number.xlsx"));
StreamingReader reader = StreamingReader.builder()
.rowCacheSize(100)
.bufferSize(4096)
.sheetIndex(0)
.read(is);
) {
for (Row row : reader) {
System.out.println("row[0] is of type " + row.getCell(0).getCellType());
Cell cell = row.getCell(0);
String value = "";
if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
value = cell.getStringCellValue();
} else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
value = "" + cell.getNumericCellValue();
}
System.out.println("Value is " + value);
}
}
}
}
给我:
所以这里没问题。
如果我将 DataFormatter
与数字单元格值一起使用:
import com.monitorjbl.xlsx.*;
import org.apache.poi.ss.usermodel.*;
import java.io.*;
class StreamingReaderTest {
public static void main(String[] args) throws Exception {
try (
InputStream is = new FileInputStream(new File("/home/axel/Downloads/test_formatted_number.xlsx"));
StreamingReader reader = StreamingReader.builder()
.rowCacheSize(100)
.bufferSize(4096)
.sheetIndex(0)
.read(is);
) {
for (Row row : reader) {
System.out.println("row[0] is of type " + row.getCell(0).getCellType());
Cell cell = row.getCell(0);
String value = "";
if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
value = cell.getStringCellValue();
} else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
value = new DataFormatter().formatCellValue(cell);
}
System.out.println("Value is " + value);
}
}
}
}
并将数字 166609647 放入 A2
中,格式为 0000000000
。然后我得到:
关于java - apache POI 将文本列读取为数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36255661/