EasyExcel 数值型和最后一列超出文本框问题

EasyExcel 数值型和最后一列超出文本框问题

Alibaba出品的EasyExcel对比原版excel库POI,极大的简化了开发人员的代码编写工作。EasyExcel使用注解和监听器等简化读写开发,

问题说明

在我的日常工作中,很大一部分的工作都是将数据库的数据整理归纳后导出为Excel,当然会碰到许许多多的问题,比如导出超时(当然这个问题大多数都是SQL执行的问题,日常几十万条数据的excel并不会花费多少时间),字段类型与需求不匹配、文本超出单元格、动态头…

这里主要记录和说明其中几个问题

  • 字段类型不匹配
  • 最后一列文本内容超出单元格

字段类型不匹配

解决方法可看easyexcel 官方github Issues :https://github.com/alibaba/easyexcel/issues/2409

问题展示

如上图所示,当我们设置实体类的属性为字符串型时,默认导出的时候数值型会模糊单元格的格式,所以上方有个三角符号,这时候excel是无法进行数值的求和汇总等运算的。

分析

我们看一下导出excel时的实体类

@Data
public class Student implements Serializable {

    @ExcelProperty( "学生编号")
    private String id;

    @ExcelProperty( "学生姓名")
    private String name;

    @ExcelProperty( "学生生日")
    @DateTimeFormat("yyyy-mm-dd")
    private Date birthday;

    @ExcelProperty("学号")
    private String stuNo;
}

注意 private String stuNo;为String类型,这里就是导致导出excel无法确定单元格格式的主要原因。

解决方法

修改方式很简单,将String改为对应的数值型格式即可如

@Data
public class Student implements Serializable {

    @ExcelProperty( "学生编号")
    private String id;

    @ExcelProperty( "学生姓名")
    private String name;

    @ExcelProperty( "学生生日")
    @DateTimeFormat("yyyy-mm-dd")
    private Date birthday;

    @ExcelProperty("学号")
    private Integer stuNo;
}

结果

PS: 第一列仍为String类型,所以导出仍有三角符号。

最后一列文本内容超出单元格

这个问题我在issues 中没有找到,可能问题比较简单😂😂😂

先说一下思路,构造出一列空值覆盖前一列内容超出部分,再手动生成标题头

问题

如果最后一列导出为长文本字符型时,很容易超出单元格,观感不佳,现象如下。

分析

我们看一下实体类多加了一个note字段,这个也就是上方长文本的字段。

@Data
public class Student implements Serializable {

    @ExcelProperty( "学生编号")
    private String id;

    @ExcelProperty( "学生姓名")
    private String name;

    @ExcelProperty( "学生生日")
    @DateTimeFormat("yyyy-mm-dd")
    private Date birthday;

    @ExcelProperty("学号")
    private Integer stuNo;

    @ExcelProperty("备注")
    private String note;
}
解决方法

我们首先看一下导出代码

EasyExcel.write("学生信息表.xlsx", Student.class)
        .sheet()
        .head(Student.class)
        .doWrite(WriteDemo.getData());

注意一下其中的方法和参数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
public class EasyExcelFactory {
    public static ExcelWriterBuilder write(String pathName, Class head) {
        ExcelWriterBuilder excelWriterBuilder = new ExcelWriterBuilder();
        excelWriterBuilder.file(pathName);
        if (head != null) {
            excelWriterBuilder.head(head);
        }

        return excelWriterBuilder;
    }
}


public abstract class AbstractParameterBuilder<T extends AbstractParameterBuilder, C extends BasicParameter> {
 

    public T head(Class clazz) {
        this.parameter().setClazz(clazz);
        return this.self();
    }
}

我们可以看到这里给excelWriterBuilder设置了一个head然后调用了AbstractParameterBuilder的head方法

head
public abstract class AbstractParameterBuilder<T extends AbstractParameterBuilder, C extends BasicParameter> {
 /***/
    public T head(Class clazz) {
        this.parameter().setClazz(clazz);
        return this.self();
    }
     /***/
    protected abstract C parameter();
     /***/
}

这里给 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进行覆盖前一列

@Data
public class Student implements Serializable {

    @ExcelProperty( "学生编号")
    private String id;

    @ExcelProperty( "学生姓名")
    private String name;

    @ExcelProperty( "学生生日")
    @DateTimeFormat("yyyy-mm-dd")
    private Date birthday;

    @ExcelProperty("学号")
    private Integer stuNo;

    @ExcelProperty("备注")
    private String note;

    // 占位符
    private String palaceHolder = "";
}

手动构造头文件

private List<List<String>> setHead() {

    List<String> list = Arrays.asList(
            "学生编号",
            "学生姓名",
            "学生生日",
            "学号",
            "备注"
    );

    return list.stream()
            .map(Arrays::asList)
            .collect(Collectors.toList());

}

最后生成excel

public void dynamicHeadWrite() {


    EasyExcel.write("学生信息表.xlsx")
            .sheet()
            .head(setHead())
            .doWrite(WriteDemo.getData());


}

结果

可以看到,最后一列内容没有超出单元格了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值