无效的标题读取xls文件

我正在读本地系统上的一个excel文件。 我正在使用POI jar版本3.7,但获取错误无效的头部签名; 读-2300849302551019537或hex0xE011BDBFEFBDBFEF,预期-2226271756974174256或hex0xE11AB1A1E011CFD0。

用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)); } 

只是一个idee,如果你使用maven确保在资源标记过滤设置为false。 否则,maven往往会在复制阶段破坏xls文件

这个例外是告诉你,你的文件不是一个有效的基于OLE2的.xls文件。

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

如果您在Excel中打开该文件并执行另存为,则可以将其作为真正的Excel文件写出。 如果你想知道它是什么文件,尝试使用Apache Tika – Tika CLI与 – --detect应该能够告诉你

我怎样才能确定它不是一个有效的文件? 如果您查看Microsoft的OLE2文件格式规范文档 ,然后转到2.2节,您将看到以下内容:

标题签名(8字节):复合文件结构的标识签名,务必设置为值0xD0,0xCF,0x11,0xE0,0xA1,0xB1,0x1A,0xE1。

翻转这些字节(OLE2是小端),你得到0xE11AB1A1E011CFD0,从exception的幻数。 你的文件不是以这个幻数开始的,因为这真的不是一个有效的OLE2文档,因此POI会给你这个例外。

如果你的项目是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(); }