"您的InputStream既不是OLE2流,也不是OOXML流"在阅读.xslx文件时

时间:2015-04-27 11:14:39

标签: java excel apache-poi

我想阅读我通过REST传递的InputStream的Excel文件。为此,我有班级ExcelImport

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

public class ExcelImport {
  public boolean readStream(InputStream stream) {
        boolean success;

        try {
            byte[] bytes = getBytes(stream);
            InputStream wrappedStream = new ByteArrayInputStream(bytes);

            Workbook workbook = WorkbookFactory.create(wrappedStream);

            for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
                Sheet sheet = workbook.getSheetAt(i);
                for (Row row : sheet) {
                    IterateThroughRow(row);
                }
            }
            success = true;
        } catch (FileNotFoundException e) {
            success = false;
            e.printStackTrace();
        } catch (IOException e) {
            success = false;
            e.printStackTrace();
        } catch (InvalidFormatException e) {
            success = false;
            e.printStackTrace();
        }
        return success;
    }

    private void IterateThroughRow(Row row) {
        Iterator<Cell> cellIterator = row.cellIterator();

        while (cellIterator.hasNext()) {
            Cell cell = cellIterator.next();

            switch (cell.getCellType()) {
                //do something with the content...
                case Cell.CELL_TYPE_STRING:
                    cell.getStringCellValue();
                    break;
                case Cell.CELL_TYPE_NUMERIC:
                    cell.getNumericCellValue();
                    break;
                case Cell.CELL_TYPE_BOOLEAN:
                    cell.getBooleanCellValue();
                    break;
                default:
            }
        }
    }

    public static byte[] getBytes(InputStream is) throws IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();

        int len;
        byte[] data = new byte[100000];
        while ((len = is.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, len);
        }

        buffer.flush();
        return buffer.toByteArray();
    }
}

如果我用这个来运行:

ExcelImport excelImport = new ExcelImport();
InputStream is = new FileInputStream("/path/to/file.xlsx");
excelImport.readStream(is);

工作正常。但是,如果我使用来自InputStream的{​​{1}}的这个类而不是REST,我会得到以下异常: PUT

我打包流,因为如果我不这样做,我会得到这个例外:java.lang.IllegalArgumentException: Your InputStream was neither an OLE2 stream, nor an OOXML stream。我是从here得到的。

是否可以使用Apache POI和来自REST的Stream读取Excel文件?或者我做错了什么?

2 个答案:

答案 0 :(得分:1)

作为此类问题的一般指南,您应该尝试将服务器收到的文件保存到磁盘。完成后,检查源和接收的文件大小是否匹配,并具有相同的校验和(例如md5)。令人惊讶的是,问题结果是转移,例如丢失文件的第一位,或者最后一位,或者在上传时损坏某些字符ascii not binary,或类似的东西

对于您的特定情况,错误意味着没有数据发送,这是个好消息。从r1677562开始,将会抛出更有用的EmptyFileException来代替为所有其他无效类型指定的更一般的Your InputStream was neither an OLE2 stream, nor an OOXML stream异常。这有望使您更容易在代码中发现此类错误的原因。该例外情况将在POI 3.12决赛中(以及之后的。

答案 1 :(得分:0)

我遇到了同样的问题,我只是将其重命名并重新保存为.xlsx电子表格,并且它可以正常工作。