无效的标题阅读xls文件(Invalid header reading xls file)

2019-07-05 20:38发布

我读我的本地系统上的一个Excel文件。 我使用POI罐子版本3.7,但得到错误的标题无效签名; 读-2300849302551019537或十六进制0xE011BDBFEFBDBFEF,预计-2226271756974174256或十六进制0xE11AB1A1E011CFD0。

打开使用Excel的XLS文件工作正常。

任何人的想法:它发生在哪里的代码块?

/**
 * create a new HeaderBlockReader from an InputStream
 *
 * @param stream the source InputStream
 *
 * @exception IOException on errors or bad data
 */
public HeaderBlockReader(InputStream stream) throws IOException {
    // At this point, we don't know how big our
    //  block sizes are
    // So, read the first 32 bytes to check, then
    //  read the rest of the block
    byte[] blockStart = new byte[32];
    int bsCount = IOUtils.readFully(stream, blockStart);
    if(bsCount != 32) {
        throw alertShortRead(bsCount, 32);
    }

    // verify signature
    long signature = LittleEndian.getLong(blockStart, _signature_offset);

    if (signature != _signature) {
        // Is it one of the usual suspects?
        byte[] OOXML_FILE_HEADER = POIFSConstants.OOXML_FILE_HEADER;
        if(blockStart[0] == OOXML_FILE_HEADER[0] &&
            blockStart[1] == OOXML_FILE_HEADER[1] &&
            blockStart[2] == OOXML_FILE_HEADER[2] &&
            blockStart[3] == OOXML_FILE_HEADER[3]) {
            throw new OfficeXmlFileException("The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)");
        }
        if ((signature & 0xFF8FFFFFFFFFFFFFL) == 0x0010000200040009L) {
            // BIFF2 raw stream starts with BOF (sid=0x0009, size=0x0004, data=0x00t0)
            throw new IllegalArgumentException("The supplied data appears to be in BIFF2 format.  "
                    + "POI only supports BIFF8 format");
        }

        // Give a generic error
        throw new IOException("Invalid header signature; read "
                              + longToHex(signature) + ", expected "
                              + longToHex(_signature));
    }

Answer 1:

只是一个爱迪,如果你使用maven在资源标签过滤确保设置为false。 否则,行家往往导致腐败XLS文件复制阶段



Answer 2:

该异常告诉你,你的文件是不是有效的基于OLE2-.xls文件。

如果能够在Excel中打开该文件是没有真正的指南 - Excel将高兴地打开它知道无论扩展是它是什么的任何文件。 如果你把一个.csv文件并将其重命名为.xls,Excel将仍然打开它,但重命名尚未神奇地使它成为.xls格式所以POI不会打开它。

如果您在Excel中打开文件,然后执行另存为,它会让你写它作为一个真正的Excel文件。 如果你想知道是什么文件,它确实是,尝试使用Apache的蒂卡 -的蒂卡CLI与--detect应该能够告诉你

我怎么能相信这不是一个有效的文件? 如果你看一下OLE2文件格式规范的文档从微软,和头部2.2节 ,你会看到以下内容:

头签名(8个字节):该化合物的文件结构鉴定签名,并且必须被设置为值0xD0,0xCF,0×11,取0xE0,0xA1,0xB1,0x1A的,0xE1。

翻转这些字节轮(OLE2是小端),你会得到0xE11AB1A1E011CFD0,从异常的幻数。 您的文件不与魔术数字开头,因为这样真的不是一个有效的OLE2文件,因此POI为您提供了异常。



Answer 3:

如果你的项目是Maven项目,下面的代码可能会有所帮助:

/**
 * Get input stream of excel.
 * <p>
 *     Get excel from src dir instead of target dir to avoid causing POI header exception.
 * </p>
 * @param fileName file in dir PROJECT_PATH/src/test/resources/excel/ , proceeding '/' is not needed.
 * @return
 */
private static InputStream getExcelInputStream(String fileName){
    InputStream inputStream = null;
    try{
        inputStream = new FileInputStream(getProjectPath() + "/src/test/resources/excel/" + fileName);
    }catch (URISyntaxException uriE){
        uriE.printStackTrace();
    }catch (FileNotFoundException fileE){
        fileE.printStackTrace();
    }
    return inputStream;
}

private static String getProjectPath() throws URISyntaxException{
    URL url = YourServiceImplTest.class.getResource("/");
    Path path = Paths.get(url.toURI());
    Path subPath = path.subpath(0, path.getNameCount() -2);
    return "/" + subPath.toString();
}


文章来源: Invalid header reading xls file