一、背景介绍
        在项目中借助POI 和 JXLS 两个开源工具jar实现excel数据导出,原有使用POI->HSSF方式进行数据导出,随着导出数据量的增大远远超出单sheet 65535条上限,将导出方式由POI->HSSF升级为POI->XSSF方式。
        术语说明:
       
JXLS:国外常用数据模版导出工具,easyPOI 是国内常用数据模版导出工具,
        POI->HSSF方式:支持Excel 97-2007版本的文件导出,单个sheet页最多能到导出65535条记录
        POI->XSSF方式:支持Excel2007以上版本的文件导出,单个sheet无条数限制

二、核心代码
        maven jar包依赖

<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.15</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.15</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schema</artifactId><version>3.15</version>
</dependency>
<dependency><groupId>net.sf.jxls</groupId><artifactId>jxls-core</artifactId><version>1.0.6</version>
</dependency>

HSSF方式:

import net.sf.jxls.transformer.XLSTransformer;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
try{//JXLS文件模版地址 文件配置详参:http://jxls.sourceforge.net/getting_started.htmlString outFilePath ="xxxx/file.xls";//数据集合Map<String, Object> dataMap = new HashMap<>();//数据赋值 略dataMap.put("users",new ArrayList<>());//加载JXLS文件模版InputStream fileStream = new FileInputStream(new File(outFilePath));//对JXLS文件模版 进行数据赋值,数据来源有XLSTransformer transformer = new XLSTransformer();HSSFWorkbook workbook = (HSSFWorkbook) transformer.transformXLS(fileStream, dataMap);//获取 excel 文件的第一个sheet页HSSFSheet sheet = workbook.getSheetAt(0);// 合并单元格操作  详参:https://poi.apache.org/apidocs/4.0/// 将第一个sheet页中的 第4列 第1行到16行进行单元格合并(行和列从0开始)sheet.addMergedRegion(new CellRangeAddress(1, 17, 3, 3));// 数据文件导出到指定目录   简化FileOutputStream fout = new FileOutputStream("xxxx/exportData.xls");workbook.write(fout);fout.close();
}catch (Throwable e){//......
}

XSSF方式:

import net.sf.jxls.transformer.XLSTransformer;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
try{//JXLS文件模版地址 文件配置详参:http://jxls.sourceforge.net/getting_started.htmlString outFilePath ="xxxx/file.xlsx";//.....同上XSSFWorkbook workbook = (XSSFWorkbook) transformer.transformXLS(fileStream, dataMap);//获取 excel 文件的第一个sheet页XSSFSheet sheet = workbook.getSheetAt(0);// 合并单元格操作  详参:https://poi.apache.org/apidocs/4.0/// 将第一个sheet页中的 第4列 第1行到16行进行单元格合并(行和列从0开始)sheet.addMergedRegion(new CellRangeAddress(1, 17, 3, 3));// 数据文件导出到指定目录   简化FileOutputStream fout = new FileOutputStream("xxxx/exportData.xlsx");workbook.write(fout);fout.close();
}catch (Throwable e){//......
}

三、XSSF问题说明
       
正主来了,升级为POI->XSSF方式后,发现生成的excel文件,合并单元格列如下所示:

发现合并后的列中的值并未清空,导致excel默认计数和求和数值不正确。经排查发现,因为POI->XSSF中进行addMergedRegion 合并单元格时并不支持“合并单元格时,仅保留左上角单元格的值,而放弃其他的值”。在excel2007版本在进行合并单元格时会默认提示如下所示:

排查了到POI 的4.1.0 版本为止,都不存在合并单元格时保留仅保留坐上角值的相关配置,于是技术上搞不定的事只能通过业务手段搞定,与业务沟通后退求其次,允许excel默认计数值错误,保证excel默认求和正确,具体操作方式如下所示:

try{//.....同上略XSSFWorkbook workbook = (XSSFWorkbook) transformer.transformXLS(fileStream, dataMap);//获取 excel 文件的第一个sheet页XSSFSheet sheet = workbook.getSheetAt(0);//将2到16行 第3列的值设置为0 for(int i=2;i<17;i++){sheet.getRow(i).getCell(3).setCellValue(0);}//.....同上略
}catch (Throwable e){//......
}

最终通过手动将需合并的1~16行中第3列,保留第1行第3列的值,将第2行到第6行的第3列的值设置为0的方式保证导出的excel文件中默认求和数据的正确性。

四、XSSF问题说明
1.IllegalArgumentException: Merged region A4 must contain 2 or more cells
   原因:由于CellRangeAddress 四个参数配置错误,计算公式为 (_lastRow - _firstRow + 1)*(_lastCol - _firstCol + 1)<2 ,通过计算公式算出可合并的行数小于2,说明没有可合并的列或行导致报错

2.org.apache.poi.openxml4j.exceptions.OLE2NotOfficeXmlFileException: The supplied data appears to be in the OLE2 Format. You are calling the part of POI that deals with OOXML (Office Open XML) Documents. You need to call a different part of POI to process this data (eg HSSF instead of XSSF) 
   原因:在使用POI->XSSF时,使用的FileInputStream 模版文件格式为file.xls导致问题产生,将模版另存为.xlsx

使用POI中XSSF 实现“合并单元格时,仅保留左上角单元格的值,而放弃其他的值“ 问题排查笔记相关推荐

  1. easypoi 如何合并相同的列,如何在Java中的POI中使用XWPFTable合并单元格(或应用colspan)?...

    Creating a table in poi was quite easy but it has very limited tutorials and I cannot find one that ...

  2. android excel合并单元格,合并单元格的同时保留所有数值

    作者:Excel Home 来源:<Excel实战技巧精粹> 发表于:2008年9月26日 合并单元格是用户在制作表格时常用的命令,它可以把多个单元格显示成一个单元格,起到美化的作用. 通 ...

  3. html怎么把excel表格合并单元格,巧用格式刷实现Excel合并后保留原单元格数据

    合并单元格是用户在制作表格时常用的命令,它可以把多个单元格显示成一个单元格,起到美化的作用. 通常情况下,如果把几个含有数据的单元格进行合并,Excel会提示"在合并单元格时,如果选择的单元 ...

  4. POI中设置Excel单元格格式样式(居中,字体,边框,背景色、列宽、合并单元格等)

    HSSFSheet sheet = workbook.createSheet("sheet1");//新建sheet页 HSSFCellStyle cellStyle = wb.c ...

  5. 使用poi来导入具有合并单元格的excel表格

    pom依赖 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml< ...

  6. POI中设置Excel单元格格式

    POI中可能会用到一些需要设置EXCEL单元格格式的操作小结: 先获取工作薄对象: HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb ...

  7. java poi导出excel,合并单元格

    java导出excel一般都是2种情况,一种是依赖一个实体类进行导出,或者把数据查询出来当成一个视图,对视图进行创建实体:另一种方式就是通过数据还要计算,然后一块统计,那么就不是很好处理了,我采用的是 ...

  8. POI进行Excel的合并单元格数据处理

    POI进行Excel的合并单元格数据处理 近日接到一个要处理合并Excel单元格的上料表的需求,就到网上找了一些模板,发现有的技术大牛还是挺厉害的,对他们致以敬意. 合并单元格工具类 在这个类中将传入 ...

  9. 使用POI创建word表格合并单元格兼容wps

    poi创建word表格合并单元格代码如下: /** * @Description: 跨列合并 */ public void mergeCellsHorizontal(XWPFTable table, ...

  10. POI操作行列、合并单元格、解决单元格边框缺少问题

    POI-操作行列单元格 一.POI-操作行 1.1 场景:直接插入行 1.2 场景:先移动旧行 再插入新行 1.3 单元格样式的设置 二.POI-操作列 三.POI-合并单元格 一.POI-操作行   ...

最新文章

  1. C#面向集合的扩展(讨论)
  2. 程序江湖:第十四章 离开让男人成长
  3. Android GridView的使用方法
  4. 寻找最大的K个数,Top K问题的堆实现
  5. 什么是野指针和内存泄露?如何避免野指针
  6. 解决《Mobile绘制背景图片》中的问题
  7. GRPC在网页前端的使用
  8. 用java编写一个图书管理系统_手把手教你编写第一个java程序
  9. leetcode - 63. 不同路径 II
  10. Jquery监听value的变化
  11. java数字转换成大写字母
  12. 解决spring-data-jpa 级联添加时,主表放弃对外键维护时外键字段为null
  13. 技术帖:如何把mobi文件转化成pdf
  14. 经典机器学习模型:朴素贝叶斯分类
  15. python大气模型算法_[学习笔记][Python机器学习:预测分析核心算法][利用Python集成方法工具包构建梯度提升模型]...
  16. 假如让你从 0 到 1 实现一个直播弹幕系统
  17. STUN和TURN技术浅析
  18. 工作后能捡起英语的三个网站
  19. STM32(C语言)内存分布
  20. 解决win10/Office2016/Onedrive/上载中心经常冲突的问题

热门文章

  1. ContentRoot 和 WebRoot 的区别
  2. 世界上5种顶级思维,你一定要知道
  3. C语言---编译器、编辑器
  4. win10打开计算机出现马赛克,传授win10系统在线播放视频出现马赛克的技巧
  5. 如何在阿里云服务器部署程序并用域名直接访问
  6. Java中的求和公式_Sympy codegen:求和索引函数
  7. 如何实现阿里云服务器数据迁移?
  8. 8. 求 s=a+aa+aaa+aaaa+aa…a 的值
  9. html怎么改表格背景,javascript修改表格背景色实例代码分享
  10. 为帮助建筑和设施管理者满足保持社交距离的需求,Bentley 软件公司开放对 LEGION Simulator 和 OpenBuildings Station Designer 的完全访问权限,并在