我正在处理一项功能,我必须通过上传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' ,奇怪的是这只发生在xlsx文件中,如果我将其保存为xls格式并重新上传文件,我检测其单元格类型没有问题。有什么想法吗?
编辑为标记为重复:
截至2016年3月29日
似乎类StreamingCell不支持DataFormatter,其中DataFormatter是目前唯一可用于获取Excel显示内容的类。因此,当前的解决方案将坚持将整个Excel文件读入内存。如果有人在将来找到答案,你可以在这里发表答案,我非常感谢,因为目前的解决方案是绝对可怕的。
截至2016年3月31日
特别感谢Axel指出其库版本问题,将流媒体jar文件更新为0.2.12解决了这个问题。谢谢!
答案 0 :(得分:2)
下载了您的文件。已下载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
。然后我明白了:
答案 1 :(得分:0)
为什么 .replaceAll(“[\ D]”,“”);
对我来说很好,只是尝试过。 想知道这里的问题是什么。
fis = new FileInputStream(inputFile);
XSSFWorkbook inputWorkBook = new XSSFWorkbook (fis);
XSSFSheet inputSheet = inputWorkBook.getSheetAt(0);
Iterator<Row> rowIterator = inputSheet.iterator();
while(rowIterator.hasNext())
{
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext())
{
Cell cell = cellIterator.next();
switch (cell.getCellType())
{
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getStringCellValue() + "\t");
break;
case Cell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue() + "\t");
break;
case Cell.CELL_TYPE_BOOLEAN:
System.out.print(cell.getBooleanCellValue() + "\t");
break;
default :
}
}
System.out.println("");
}