使用Easy-POI导入复杂表头的Excel报表(含源码级分析)

本文旨在解决使用Easy-POI导入复杂表头(导出)时,遇上的EXCEL文件中的字段无法正常映射到Bean的问题,官方的示例和其他的CSDN文章基本上没有很详细的教程,于是自己写一个

这是需要导入的表结构:在这里插入图片描述

这是结构中需要在ImportParams中声明的术语:
在这里插入图片描述
在导入的时候,必须通过ImportParams params = new ImportParams()对象设置表的基本结构,如果有标题,就要params.setTitleRows(1)设置忽略的行,标题占1行就设置1,占n行就设置n,这个很容易

需要特别注意的是headRows,这里需要设置的是表头行的行数,默认情况下为1,但如果使用的是复杂表头,则表头占的行数就不是1了,比如示例中的表头一样,b分组下有c和d,e分组下也有c和d(严格上来说是b分组下只有c,e分组下也只有c,下面我会说原因),表头显然占了2行(别纠结a字段貌似只占了一行!实际肯定是要以最大为主。而且最左边列的数字也能看出占了2行,以最左边的数字为准就行了!),最后params.setHeadRows(2)搞定!

然后Excel的数据导入就能正确解析了,看看解析成什么样子?

在这里插入图片描述
下面要讲解Bean的解析了,要让Excel正确生成Bean,显然Excel上是没法下功夫的,因为Excel都是客户给的需求,已经是硬性规定了,只能在Bean上下功夫,来看看Bean是怎样的

这是第一版的Bean
在这里插入图片描述
这里有人会问我为什么不给d属性和g属性加groupName属性吗?这里我有必要加吗?groupName属性的作用就是把Bean中的c变成b_c,e_c,使之上面的titleMap的字段相对应,上面的d字段并没有被解析成b_d,e_d,加了反而映射不上。因为easypoi认为,虽然b字段占了1,2两列,但他在归属上任然只算列数1,所以解析的时候只会处理同为列数1的c字段并合并为b_c,列数2的d字段已经是独立的字段了,并不会处理成b_d,e字段也是同理。然后看看结果如何。。。

在这里插入图片描述
看看Bean中解析出的属性有没有问题

在这里插入图片描述

原理:

在这里插入图片描述
大致过程如下:
遍历真实数据行备用;
遍历Excel中解析出的字段集合titleMap并获得对应的列数与字段名 ------> 根据集合中的字段名称获取Bean中解析出的ExcelImportEntity对象 ------> 拿出ExcelImportEntity对象中早以准备好的set方法对象,然后new出来的bean,依据titleMap中的列数和真实数据行获取的真实数据--------->填充Bean的其中一个属性

也就是说,案例中Bean的属性G会通过ExcelImportEntity中的setG方法重复设置2次,由于属性G对应的d字段是最后一个字段,属性G也是@Excel中name为d的最后一个属性(这点可以保证,因为生成ExcelImportEntity集合的excelParams也是通过循环的方式,所以不会出现4个ExcelImportEntity对象中setG方法的对象被setD方法覆盖),所以覆盖到最后,值总是对的

分析完原因之后,解决的方案很简单,通过fixIndex解决@Excel中name重名问题:
在这里插入图片描述
看看加完以后bean的属性集合变成什么样。。。
在这里插入图片描述
bean的映射集中原来缺失的d属性的映射集多了一个FIXED_2

在这里插入图片描述
接下来就容易多了,只要读取要字段开头为“FIX_”开头的Bean属性映射集,直接获取列数,通过列数(titleMap中的key)获取对应的真实数据即可,不需在通过Excel中的列名(titleMap中的value)获取,完成!

深入

这个更复杂的表现在应该会了吧
在这里插入图片描述
先在导入参数中设置好标题行数和表头行数,上表中标题占了1行,表头占了3行
在这里插入图片描述
然后配置好Bean类中的注解,需要注意一下,像f属性所映射的c字段这种有多个复杂表头匹配的项x2和b字段同时重合,直接a字段_b字段_…就行
在这里插入图片描述
最后结果:
在这里插入图片描述

如果复杂表头下的子字段名称都是不一样的怎么办?那更简单,连fixIndex都可以省略了。
如果需要单独一个实体类映射复杂表头直接@ExcelEntity就行,毕竟举例中出现字段名相同的情况才是最难的情况,其他的都是简单情况

  • 27
    点赞
  • 87
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
使用POI-OOXML导入Excel时,您可以使用注解或XML配置来将Excel列与Java对象字段对应起来。 1. 使用注解 您可以在Java对象的字段上使用注解来指定Excel列的名称或索引。例如,假设您有一个名为Employee的Java类,其中包id、name和age字段。您可以在该类中使用以下注解: ```java public class Employee { @ExcelColumn("ID") private int id; @ExcelColumn("Name") private String name; @ExcelColumn("Age") private int age; // 省略getter和setter方法 } ``` 在这个例子中,@ExcelColumn注解告诉POIExcel列“ID”映射到id字段,将Excel列“Name”映射到name字段,将Excel列“Age”映射到age字段。 2. 使用XML配置 如果您不想在Java类中使用注解,您可以使用XML配置文件来指定Excel列与Java对象字段之间的映射关系。例如,假设您有一个名为employee.xml的配置文件,其中包以下内容: ```xml <?xml version="1.0" encoding="UTF-8"?> <excel-mapping> <class name="com.example.Employee"> <column name="ID" field="id" /> <column name="Name" field="name" /> <column name="Age" field="age" /> </class> </excel-mapping> ``` 在这个例子中,<column>元素指定Excel列的名称和Java对象字段的名称。您可以在使用POI-OOXML导入Excel时指定这个配置文件,如下所示: ```java ExcelReader reader = new ExcelReader(new FileInputStream("path/to/excel/file.xlsx"), "Sheet1", "employee.xml"); List<Employee> employees = reader.read(Employee.class); ``` 在这个例子中,ExcelReader类使用employee.xml配置文件将Excel列映射到Employee类的字段。您可以根据需要创建多个配置文件,每个文件都可以映射不同的Excel列到不同的Java对象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值