apache POI将文本列读取为数字

时间:2016-03-28 03:47:12

标签: java excel apache apache-poi

我正在处理一项功能,我必须通过上传excel文件存储收到的号码。它是用Java编写的,使用apache poi库,在Spring框架下(这是无关紧要的)。

我尝试上传的文件(请注意该列已设置为文字):

enter image description here

代码如下:

// 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类,当我们传输工作表时不支持该类,因为检索到的Cell对象将成为StreamingCell对象,如果我们调用getCellStyle()则抛出异常功能

截至2016年3月29日

似乎类StreamingCell不支持DataFormatter,其中DataFormatter是目前唯一可用于获取Excel显示内容的类。因此,当前的解决方案将坚持将整个Excel文件读入内存。如果有人在将来找到答案,你可以在这里发表答案,我非常感谢,因为目前的解决方案是绝对可怕的。

截至2016年3月31日

特别感谢Axel指出其库版本问题,将流媒体jar文件更新为0.2.12解决了这个问题。谢谢!

2 个答案:

答案 0 :(得分:2)

下载了您的文件。已下载xlsx-streamer-0.2.12.jarslf4j-api-1.7.20.jarslf4j-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);
   }
  }
 }
}

给我:

enter image description here

这里没问题。

如果我将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。然后我明白了:

enter image description here

答案 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(""); 
}