使用poi-ooxml-full.jar包过程中出现的版本问题
先看报错信息:
Exception in thread "main" org.apache.poi.ooxml.POIXMLException: org.apache.logging.log4j.Logger.atTrace()Lorg/apache/logging/log4j/LogBuilder; at org.apache.poi.ooxml.POIXMLFactory.createDocumentPart(POIXMLFactory.java:66) at org.apache.poi.ooxml.POIXMLDocumentPart.read(POIXMLDocumentPart.java:648) at org.apache.poi.ooxml.POIXMLDocument.load(POIXMLDocument.java:180) at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:286) at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:307) at com.tobiasy.pdf.cloud.pdfcloud.service.excel.ExcelWaterMarkUtils.getWorkbook(ExcelWaterMarkUtils.java:50) at com.tobiasy.pdf.cloud.pdfcloud.service.excel.ExcelWaterMarkUtils.remove(ExcelWaterMarkUtils.java:20) at com.tobiasy.pdf.cloud.pdfcloud.service.excel.PdfConvertExcelUtils.convertToExcel(PdfConvertExcelUtils.java:41) at com.tobiasy.pdf.cloud.pdfcloud.service.excel.PdfConvertExcelUtils.main(PdfConvertExcelUtils.java:24) Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.apache.poi.xssf.usermodel.XSSFFactory.createDocumentPart(XSSFFactory.java:56) at org.apache.poi.ooxml.POIXMLFactory.createDocumentPart(POIXMLFactory.java:63) ... 8 more Caused by: java.lang.NoSuchMethodError: org.apache.logging.log4j.Logger.atTrace()Lorg/apache/logging/log4j/LogBuilder; at org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl.<init>(SchemaTypeSystemImpl.java:196) at org.apache.xmlbeans.metadata.system.sXMLCONFIG.TypeSystemHolder.<init>(TypeSystemHolder.java:9) at org.apache.xmlbeans.metadata.system.sXMLCONFIG.TypeSystemHolder.<clinit>(TypeSystemHolder.java:6) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:348) at org.apache.xmlbeans.impl.schema.SchemaTypeLoaderImpl.build(SchemaTypeLoaderImpl.java:161) at org.apache.xmlbeans.impl.schema.SchemaTypeLoaderImpl.build(SchemaTypeLoaderImpl.java:131) at org.apache.xmlbeans.XmlBeans.typeLoaderForClassLoader(XmlBeans.java:425) at org.openxmlformats.schemas.spreadsheetml.x2006.main.StyleSheetDocument$Factory.getTypeLoader(Unknown Source) at org.openxmlformats.schemas.spreadsheetml.x2006.main.StyleSheetDocument$Factory.parse(Unknown Source) at org.apache.poi.xssf.model.StylesTable.readFrom(StylesTable.java:189) at org.apache.poi.xssf.model.StylesTable.<init>(StylesTable.java:138) ... 14 more
错误日志中乍一看呢其实就是版本问题了,那么我们怎么来解决呢?
首先我们先看看依赖poi-ooxml-full配置:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-full</artifactId> <version>5.1.0</version> </dependency>
首先我们去Maven中找到该依赖的几个版本号,如下:
然后我们尝试切换了所有的版本号,发现每一个版本号可以使用,那么问题来了,难道是这个依赖包真的不能使用吗?
我们继续往下看
首先,锁定关键信息:org.apache.poi.ooxml.POIXMLException: org.apache.logging.log4j.Logger.atTrace()Lorg/apache/logging/log4j/LogBuilder;
我们会看到提示:Logger类和LogBuilder类都找不到,我们通过编译器去搜索也确实找不到!
那么我们再看这两个类都有一个共同的包名:org.apache.logging.log4j
那是不是缺少log4j这个依赖呢?然后我们通过idea来展开看,竟然是有的!!
那是不是log4j-api冲突了呢?
那我们来继续尝试:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-full</artifactId> <version>5.1.0</version> <exclusions> <exclusion> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.12.1</version> </dependency>
此时依赖没有出现冲突了,我们通过Idea来看看:
目前没出现冲突了,那我们继续执行代码看看是否还会报错……
容器启动中……
我的个神呐,还是同样的错!!!!!!
好吧,容我先翻阅一下资料…………
去网上看了一下,有人说是xmlbeans依赖的问题,我勒个去,这是内部jar包的版本号呀,还能有错吗
好吧,我处理一下试试……
处理完之后发现xmlbeans版本换了好几个都是一样的,一直到使用到版本号3.1.0,问题终于解决了!!!
汇总一下,可用的版本号只有图中红色标注这几个:
查看原因:
3.0.0版本及其之前报错:org.apache.xmlbeans.XmlOptions.setEntityExpansionLimit(I)
4.0.0版本及其之后报错:java.lang.NoSuchMethodError: org.apache.xmlbeans.XmlOptions.put(Ljava/lang/Object;)V
换句话说就是,低版本的XmlOptions对象中没有setEntityExpansionLimit方法,高版本的又没有put方法!!!
所以最终解决方案如下:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-full</artifactId> <version>5.1.0</version> <exclusions> <exclusion> <groupId>org.apache.xmlbeans</groupId> <artifactId>xmlbeans</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.xmlbeans</groupId> <artifactId>xmlbeans</artifactId> <version>4.0.0</version> </dependency>
小结:依赖poi-ooxml-full.jar是一个巨坑,大家使用的时候一定要注意。