当前位置: 首页 > 知识库问答 >
问题:

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

鄢晔
2023-03-14

我想读取Excel文件,这些文件以inputstream的形式通过REST传递。为此,我有类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一起使用,来自putover REST的java.lang.IllegalArgumentException:您的InputStream既不是OLE2流,也不是OOXML流

我包装流是因为如果我不这样做,我会得到这个异常:包应该包含一个内容类型部分。我从这里得到的。

难道不能使用Apache POI和REST中的流来读取Excel文件吗?还是我做错了什么?

共有1个答案

公冶元青
2023-03-14

对于这类问题,您应该尝试将服务器接收到的文件保存到磁盘上。完成此操作后,检查源文件和接收文件的大小是否匹配,并具有相同的校验和(例如md5)。令人惊讶的是,问题往往是传输,例如丢失文件的第一位或最后一位,或者在以ascii而不是二进制形式上传时损坏某些字符,或者类似的事情

对于您的bug的特定情况意味着没有数据被发送,有一个好消息。从r1677562开始,将抛出一个更有帮助的EmptyFileException来代替更一般的您的InputStream既不是OLE2流,也不是针对所有其他无效类型的OOXML流异常。希望这样可以更容易地发现代码中这种类型的bug的原因。这个例外将出现在POI3.12final(及以后)中。

 类似资料: