EasyExcel 数值型和最后一列超出文本框问题
EasyExcel 数值型和最后一列超出文本框问题
Alibaba出品的EasyExcel对比原版excel库POI,极大的简化了开发人员的代码编写工作。EasyExcel使用注解和监听器等简化读写开发,
问题说明
在我的日常工作中,很大一部分的工作都是将数据库的数据整理归纳后导出为Excel,当然会碰到许许多多的问题,比如导出超时(当然这个问题大多数都是SQL执行的问题,日常几十万条数据的excel并不会花费多少时间),字段类型与需求不匹配、文本超出单元格、动态头…..
这里主要记录和说明其中几个问题
- 字段类型不匹配
- 最后一列文本内容超出单元格
字段类型不匹配
解决方法可看easyexcel 官方github Issues :https://github.com/alibaba/easyexcel/issues/2409
问题展示
如上图所示,当我们设置实体类的属性为字符串型时,默认导出的时候数值型会模糊单元格的格式,所以上方有个三角符号,这时候excel是无法进行数值的求和汇总等运算的。
分析
我们看一下导出excel时的实体类
1 |
|
注意 private String stuNo;
为String类型,这里就是导致导出excel无法确定单元格格式的主要原因。
解决方法
修改方式很简单,将String改为对应的数值型格式即可如
1 |
|
结果
PS: 第一列仍为String类型,所以导出仍有三角符号。
最后一列文本内容超出单元格
这个问题我在issues 中没有找到,可能问题比较简单:joy::joy::joy:
先说一下思路,构造出一列空值覆盖前一列内容超出部分,再手动生成标题头
问题
如果最后一列导出为长文本字符型时,很容易超出单元格,观感不佳,现象如下。
分析
我们看一下实体类多加了一个note字段,这个也就是上方长文本的字段。
1 |
|
解决方法
我们首先看一下导出代码
1 | EasyExcel.write("学生信息表.xlsx", Student.class) |
注意一下其中的方法和参数write()和head()
write()重载方法入参
- File file
- File file,@Nullable Class head
- String pathName
- String pathName, @Nullable Class head
- outputStream outputStream
- outputStream outputStream, @Nullable Class head
所有的重载方法入参第一个都是确定文件名称(File )和位置(pathName),outputStream 是web上传、下载。我们关注后面一个参数 Class head
这里指定了导出文件的head,同head方法功能相似,也就是说,这里我们去到 .head(Student.class)
或者.write("学生信息表.xlsx", Student.class)
中的Student.class
都是正常的。
简单分析一下源代码
write
1 | public class EasyExcelFactory { |
我们可以看到这里给excelWriterBuilder
设置了一个head
然后调用了AbstractParameterBuilder
的head方法
head
1 | public abstract class AbstractParameterBuilder<T extends AbstractParameterBuilder, C extends BasicParameter> { |
这里给 this.parameter()
设置了类名,这里的this.parameter指的是AbstractParameterBuilder
中的protected abstract C parameter();
方法,我们可以看到,这里其实本质上是调用了同一个方法。
head的特别之处
head方法本质上是用来动态生成头文件的,详情可参照官方文档https://easyexcel.opensource.alibaba.com/docs/current/quickstart/write#%E5%8A%A8%E6%80%81%E5%A4%B4%E5%AE%9E%E6%97%B6%E7%94%9F%E6%88%90%E5%A4%B4%E5%86%99%E5%85%A5
如果我们再write方法上没有指定标题头,则可以手动通过head方法构造,这样我们就可以实现最后一列不出单元格了
具体实现
先修改导出实体类添加一个占位符并赋初始值为空(注意,如果没有赋值为空字符串,则不会写入excel进行覆盖前一列)
1 |
|
手动构造头文件
1 | private List<List<String>> setHead() { |
最后生成excel
1 | public void dynamicHeadWrite() { |
结果
可以看到,最后一列内容没有超出单元格了。