java 读取 .xslx 文件时“您的 InputStream 既不是 OLE2 流,也不是 OOXML 流”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29894185/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 16:05:32  来源:igfitidea点击:

"Your InputStream was neither an OLE2 stream, nor an OOXML stream" while reading .xslx File

javaexcelapache-poi

提问by Peter

I want to read Excel files which I get passed over REST as InputStream. For this I have the class ExcelImport:

我想读取通过 REST 作为InputStream. 为此,我有课程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();
    }
}

If I run this with this:

如果我用这个运行它:

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

It works fine. But if I use this class with a InputStreamfrom a PUTover REST I get this Exception: java.lang.IllegalArgumentException: Your InputStream was neither an OLE2 stream, nor an OOXML stream

它工作正常。但是,如果我将此类与InputStream来自PUTREST 的a一起使用,则会出现此异常: java.lang.IllegalArgumentException: Your InputStream was neither an OLE2 stream, nor an OOXML stream

I wrap the stream because if I don't do it, I get this Exception: Package should contain a content type part. I got this from here.

我包装了流,因为如果我不这样做,我会得到这个 Exception: Package should contain a content type part。我从这里得到了这个。

Isn't it possible to read Excel files using Apache POI with a Stream from REST? Or am I doing something else wrong?

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

采纳答案by Gagravarr

As a general guide for this sort of problem, you should try saving the file received by your server to disk. Having done that, check that the source and received file sizes match, and have the same checksum (eg md5). Surprisingly often, the problem turns out to be the transfer, eg loosing the first bit of the file, or the last bit, or corrupting certain characters when uploading as ascii not binary, or something like that

作为此类问题的一般指南,您应该尝试将服务器收到的文件保存到磁盘。完成后,检查源文件大小和接收文件大小是否匹配,并具有相同的校验和(例如 md5)。经常出人意料的是,问题出在传输上,例如丢失文件的第一位或最后一位,或者在以 ascii 而非二进制上传时损坏某些字符,或类似的东西

For your specific case of a bug meaning no data is sent, there's good news. As of r1677562, a more helpful EmptyFileExceptionwill be thrown in place of the more general Your InputStream was neither an OLE2 stream, nor an OOXML streamexception given for all other invalid types. This should hopefully make it easier to spot the cause of this style of bug in your code. That exception will be in POI 3.12 final (and later.

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

回答by Djandli

I had the same problem and I simply renamed and resaved as .xlsx the spreadsheetand it worked.

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