ApachePOI将文本列读取为数字

piztneat  于 2021-07-13  发布在  Java
关注(0)|答案(2)|浏览(354)

我正在开发一个函数,在这个函数中,我必须存储通过上传excel文件收到的数字。它是用java编写的,使用ApachePOI库,在spring框架下(这是不相关的)。
我试图上载的文件(请注意,该列已设置为text):

代码如下:

// 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格式并重新上传该文件,我没有问题检测其单元格类型。有什么想法吗?
为标记为复制而编辑:
给出答案https://stackoverflow.com/a/19401902/1131470 当我们对工作表进行流式处理时,使用不支持的dataformatter类,因为检索到的单元格对象将是streamingcell对象,如果调用getcellstyle()函数,它将引发异常。
截至2016年3月29日
似乎streamingcell类不支持dataformatter,dataformatter是目前唯一可以获取excel显示内容的类。因此,当前的解决方案是将整个excel文件读入内存。如果有人在未来找到答案,请在这里张贴一个答案,我会非常感激,因为目前的解决方案是一个绝对可怕的。
截至2016年3月31日
特别感谢axel指出了它的库版本问题,将StreamerJAR文件更新到0.2.12解决了这个问题。谢谢!

vfhzx4xs

vfhzx4xs1#

下载了你的文件。已下载 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 . 然后我得到:

ffdz8vbo

ffdz8vbo2#

why.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(""); 
}

相关问题