官方文档:
1.1 介绍 - Powered by MinDoc
导入easypoi依赖,版本可以选择最新的
<!--easyPoi-->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>4.1.2</version>
</dependency>
前端传输Excel文件到后端,文件中有一列是图片,现在的问题是,有的excel文件能够正常导入,有的excel文件导入的时候报空指针异常。
后端代码如下:
使用ExcelImportUtil.importExcelMore(......)方法去处理接收到的excel
但是报错了,空指针异常:
java.lang.NullPointerException:
at org.apache.poi.xssf.usermodel.XSSFClientAnchor.setCol2(XSSFClientAnchor.java:231)
............................................
什么原因呢? 看代码:
ImageUtils.java类
anchor.setCol2(col2);
anchor.setDx2(dx2);
anchor接口的实现类是:XSSFClientAnchor.java
之所以报空指针值异常是因为cell2这个类属性未赋值,从而导致了空指针异常
public void setCol2(int col2){
cell2.setCol(col2);
}
XSSFClientAnchor.java类是怎样实例化的?答案就在这里,下面的代码中,根据parentXbean类的类型,使用不同的构造方法去new一个XSSFClientAnchor类
-
在类型为CTTwoCellAnchor的时候,使用 new XSSFClientAnchor(ct.getFrom(), ct.getTo()),这是2个参数的构造方法,在里面对cell2进行了赋值,所以不会出现空指针异常
-
在类型为CTOneCellAnchor的时候,使用 new XSSFClientAnchor(getSheet(),ct.getFrom(), ct.getTo()),这是3个参数的构造方法,在里面未对cell2进行赋值,所以会出现空指针异常
private XSSFAnchor getAnchorFromParent(XmlObject obj) {
XSSFAnchor anchor = null;
XmlObject parentXbean = null;
XmlCursor cursor = obj.newCursor();
if (cursor.toParent()) {
parentXbean = cursor.getObject();
}
cursor.dispose();
if (parentXbean != null) {
if (parentXbean instanceof CTTwoCellAnchor) {
CTTwoCellAnchor ct = (CTTwoCellAnchor) parentXbean;
anchor = new XSSFClientAnchor(ct.getFrom(), ct.getTo());
} else if (parentXbean instanceof CTOneCellAnchor) {
CTOneCellAnchor ct = (CTOneCellAnchor) parentXbean;
anchor = new XSSFClientAnchor(getSheet(), ct.getFrom(), ct.getExt());
} else if (parentXbean instanceof CTAbsoluteAnchor) {
CTAbsoluteAnchor ct = (CTAbsoluteAnchor) parentXbean;
anchor = new XSSFClientAnchor(getSheet(), ct.getPos(), ct.getExt());
}
}
return anchor;
}
这是怎么回事呢?
出问题的时候用的是CTOneCellAnchor, 正常工作的时候用的是CTTwoCellAnchor,为什么会这样呢?到底是什么导致了几乎相同的excel文件导入出现不同的结果?
解决方案:
看这篇文章:
61203 – XSSFDrawing.getAnchorFromParent handles CTOneCellAnchor incorrectly, ignores CTAbsoluteAnchor
里面有这么一段:
I think the Excel chart/shape properties map like this:
- Move and size with cells == CTTwoCellAnchor
- Move but don't size with cells == CTOneCellAnchor
- Don't move or size with cells == CTAbsoluteAnchor
CTTwoCellAnchor是指图片的大小和位置随着单元格而变
CTOneCellAnchor是指大小固定,位置随着单元格而变
我们是否可以通过设置Excel表格中的图片格式属性来解决这个问题呢?
将属性设置为随单元格改变位置和大小,问题解决了,所以归根结底,还是因为excel中图片格式属性的问题。
![](https://img-blog.csdnimg.cn/img_convert/905c177e3f30b2aeec181e48b8c2b40f.webp?x-oss-process=image/format,png)
![](https://img-blog.csdnimg.cn/img_convert/56821929516122411a09e59086f92a41.webp?x-oss-process=image/format,png)