需求背景
最近工作中需要将两个文件夹下面相同的excle做对比,并生成一个汇总后的excle,同一类表格按照机构区分,包含多个数据表,需要将一类报表按照机构不同汇总到新的excle中,按照机构号生成不同的sheet,每个sheet中需要将两个文件按行复制在一起,并自动生成一个最新的对比列,对比列需要将数值部分自动计算体现差异,历时两个星期最终完成了此项功能,记录一下过程中发生的印象深刻的bug。
HSSFWorkbook 遭遇 java.lang.NullPointerException
遇到空指针,哎呦头疼,有的好解决,有的莫名其妙,excle的空指针更是莫名其妙。
Exception in thread "main" java.lang.NullPointerException
at org.apache.poi.hssf.record.FormatRecord.getDataSize(FormatRecord.java:110)
at org.apache.poi.hssf.record.StandardRecord.getRecordSize(StandardRecord.java:38)
at org.apache.poi.hssf.model.InternalWorkbook.getSize(InternalWorkbook.java:1072)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.getBytes(HSSFWorkbook.java:1474)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.write(HSSFWorkbook.java:1386)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.write(HSSFWorkbook.java:1374)
使用输出流写入workbook的时候爆出来的,读取没有问题,更奇怪的是点开原始excle重新保存一下就没有问题了,于是果断追踪源代码,看一下这个这个代码保存了什么,最终看到InternalWorkbook类在写入的时候会获取FormatRecord的size(),从这个入手debugger,功夫不负有心人啊,最终在debug的时候发现
[FORMAT]
.indexcode = 0x03AD
.indexcode = 941
.isUnicode = false
.formatstring = null
[/FORMAT]
不知道这个是干什么的,但是formatstring 很清晰,查询api发现HSSFCellStyle存在getDataFormatString()方法,到此就很接近了,检查代码发现在复制单元格的时候使用了cloneStyleFrom()方法,直接将有问题的单元格复制到新的workbook了导致空指针,果断改代码:
HSSFCellStyle tmpStyles = tmpCell.getCellStyle();
if(tmpStyles.getDataFormatString() ==null){
HSSFCellStyle newExcelStyle1 = workbook.createCellStyle();
newExcelStyle1.setDataFormat(HSSFDataFormat.getBuiltinFormat("General"));
// 单元格样式
newExcelCell.setCellStyle(newExcelStyle1);
}else{
// 复制单元格样式
newExcelStyle.cloneStyleFrom(tmpStyles);
// 单元格样式
newExcelCell.setCellStyle(newExcelStyle);
}
测试通过!
过程很艰难,加油!