自从用了 EasyExcel,导入导出 Excel 更简单了!(easyexcel导出到指定路径)

  本篇文章为你整理了自从用了 EasyExcel,导入导出 Excel 更简单了!(easyexcel导出到指定路径)的详细内容,包含有easyexcel导出文件到本地 easyexcel导出到指定路径 easyui excel导入 easyexcel导出大量数据 自从用了 EasyExcel,导入导出 Excel 更简单了!,希望能帮助你了解 自从用了 EasyExcel,导入导出 Excel 更简单了!。

  分享Java技术,高并发编程,分布式技术,架构设计,Java面试题,算法,行业动态,程序人生等。

  
EasyExcel

  在做excel导入导出的时候,发现项目中封装的工具类及其难用,于是去gitHub上找了一些相关的框架,最终选定了EasyExcel。之前早有听闻该框架,但是一直没有去了解,这次借此学习一波,提高以后的工作效率。

  实际使用中,发现是真的很easy,大部分api通过名称就能知道大致意思,这点做的很nice。参考文档,大部分场景的需求基本都能够满足。

  GitHub上的官方说明

  maven仓库地址

  

 dependency 

 

   groupId com.alibaba /groupId

   artifactId easyexcel /artifactId

   version 2.1.2 /version

   /dependency

  

 

  推荐一个开源免费的 Spring Boot 最全教程:

  https://github.com/javastacks/spring-boot-best-practice

  如下图excel表格:

  建立导入对应实体类

  

@Data

 

  public class ReqCustomerDailyImport {

   * 客户名称

   @ExcelProperty(index = 0)

   private String customerName;

   * MIS编码

   @ExcelProperty(index = 1)

   private String misCode;

   * 月度滚动额

   @ExcelProperty(index = 3)

   private BigDecimal monthlyQuota;

   * 最新应收账款余额

   @ExcelProperty(index = 4)

   private BigDecimal accountReceivableQuota;

   * 本月利率(年化)

   @ExcelProperty(index = 5)

   private BigDecimal dailyInterestRate;

  

 

  Controller代码

  

@PostMapping("/import")

 

  public void importCustomerDaily(@RequestParam MultipartFile file) throws IOException {

   InputStream inputStream = file.getInputStream();

   List ReqCustomerDailyImport reqCustomerDailyImports = EasyExcel.read(inputStream)

   .head(ReqCustomerDailyImport.class)

   // 设置sheet,默认读取第一个

   .sheet()

   // 设置标题所在行数

   .headRowNumber(2)

   .doReadSync();

  

 

  可以看出只需要在实体对象使用@ExcelProperty注解,读取时指定该class,即可读取,并且自动过滤了空行,对于excel的读取及其简单。不过此时发现一个问题,这样我如果要校验字段该怎么办?要将字段类型转换成另外一个类型呢?

  不必担心,我们可以想到的问题,作者肯定也考虑到了,下面来一个Demo

  

List ReqCustomerDailyImport reqCustomerDailyImports = EasyExcel.read(inputStream)

 

   // 这个转换是成全局的, 所有java为string,excel为string的都会用这个转换器。

   // 如果就想单个字段使用请使用@ExcelProperty 指定converter

   .registerConverter(new StringConverter())

   // 注册监听器,可以在这里校验字段

   .registerReadListener(new CustomerDailyImportListener())

   .head(ReqCustomerDailyImport.class)

   .sheet()

   .headRowNumber(2)

   .doReadSync();

  

 

  

public class CustomerDailyImportListener extends AnalysisEventListener {

 

   List misCodes = Lists.newArrayList();

   * 每解析一行,回调该方法

   * @param data

   * @param context

   @Override

   public void invoke(Object data, AnalysisContext context) {

   String misCode = ((ReqCustomerDailyImport) data).getMisCode();

   if (StringUtils.isEmpty(misCode)) {

   throw new RuntimeException(String.format("第%s行MIS编码为空,请核实", context.readRowHolder().getRowIndex() + 1));

   if (misCodes.contains(misCodes)) {

   throw new RuntimeException(String.format("第%s行MIS编码已重复,请核实", context.readRowHolder().getRowIndex() + 1));

   } else {

   misCodes.add(misCode);

   * 出现异常回调

   * @param exception

   * @param context

   * @throws Exception

   @Override

   public void onException(Exception exception, AnalysisContext context) throws Exception {

   // ExcelDataConvertException:当数据转换异常的时候,会抛出该异常,此处可以得知第几行,第几列的数据

   if (exception instanceof ExcelDataConvertException) {

   Integer columnIndex = ((ExcelDataConvertException) exception).getColumnIndex() + 1;

   Integer rowIndex = ((ExcelDataConvertException) exception).getRowIndex() + 1;

   String message = "第" + rowIndex + "行,第" + columnIndex + "列" + "数据格式有误,请核实";

   throw new RuntimeException(message);

   } else if (exception instanceof RuntimeException) {

   throw exception;

   } else {

   super.onException(exception, context);

   * 解析完全部回调

   * @param context

   @Override

   public void doAfterAllAnalysed(AnalysisContext context) {

   misCodes.clear();

  

 

  

public class StringConverter implements Converter String {

 

   @Override

   public Class supportJavaTypeKey() {

   return String.class;

   @Override

   public CellDataTypeEnum supportExcelTypeKey() {

   return CellDataTypeEnum.STRING;

   * 将excel对象转成Java对象,这里读的时候会调用

   * @param cellData NotNull

   * @param contentProperty Nullable

   * @param globalConfiguration NotNull

   * @return

   @Override

   public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty,

   GlobalConfiguration globalConfiguration) {

   return "自定义:" + cellData.getStringValue();

   * 将Java对象转成String对象,写出的时候调用

   * @param value

   * @param contentProperty

   * @param globalConfiguration

   * @return

   @Override

   public CellData convertToExcelData(String value, ExcelContentProperty contentProperty,

   GlobalConfiguration globalConfiguration) {

   return new CellData(value);

  

 

  可以看出注册了一个监听器:CustomerDailyImportListener,还注册了一个转换器:StringConverter。流程为:框架读取一行数据,先执行转换器,当一行数据转换完成,执行监听器的回调方法,如果转换的过程中,出现转换异常,也会回调监听器中的onException方法。因此,可以在监听器中校验数据,在转换器中转换数据类型或者格式。

  修改一下表格,测试校验是否生效

  再次导入,查看运行结果

  导入相关常用API

  ExcelProperty 指定当前字段对应excel中的那一列。可以根据名字或者Index去匹配。当然也可以不写,默认第一个字段就是index=0,以此类推。千万注意,要么全部不写,要么全部用index,要么全部用名字去匹配。千万别三个混着用,除非你非常了解源代码中三个混着用怎么去排序的。

  ExcelIgnore 默认所有字段都会和excel去匹配,加了这个注解会忽略该字段。

  DateTimeFormat 日期转换,用String去接收excel日期格式的数据会调用这个注解。里面的value参照java.text.SimpleDateFormat。

  NumberFormat 数字转换,用String去接收excel数字格式的数据会调用这个注解。里面的value参照java.text.DecimalFormat。

  EasyExcel相关参数

  readListener 监听器,在读取数据的过程中会不断的调用监听器。

  converter 转换器,默认加载了很多转换器。也可以自定义,如果使用的是registerConverter,那么该转换器是全局的,如果要对单个字段生效,可以在ExcelProperty注解的converter指定转换器。

  headRowNumber 需要读的表格有几行头数据。默认有一行头,也就是认为第二行开始起为数据。

  head 与clazz二选一。读取文件头对应的列表,会根据列表匹配数据,建议使用class。

  autoTrim 字符串、表头等数据自动trim。

  sheetNo 需要读取Sheet的编码,建议使用这个来指定读取哪个Sheet。

  sheetName 根据名字去匹配Sheet,excel 2003不支持根据名字去匹配。

  建立导出对应实体类

  

@Data

 

  @Builder

  public class RespCustomerDailyImport {

   @ExcelProperty("客户编码")

   private String customerName;

   @ExcelProperty("MIS编码")

   private String misCode;

   @ExcelProperty("月度滚动额")

   private BigDecimal monthlyQuota;

   @ExcelProperty("最新应收账款余额")

   private BigDecimal accountReceivableQuota;

   @NumberFormat("#.##%")

   @ExcelProperty("本月利率(年化)")

   private BigDecimal dailyInterestRate;

  

 

  Controller代码

  

@GetMapping("/export")

 

  public void export(HttpServletResponse response) throws IOException {

   // 生成数据

   List RespCustomerDailyImport respCustomerDailyImports = Lists.newArrayList();

   for (int i = 0; i i++) {

   RespCustomerDailyImport respCustomerDailyImport = RespCustomerDailyImport.builder()

   .misCode(String.valueOf(i))

   .customerName("customerName" + i)

   .monthlyQuota(new BigDecimal(String.valueOf(i)))

   .accountReceivableQuota(new BigDecimal(String.valueOf(i)))

   .dailyInterestRate(new BigDecimal(String.valueOf(i))).build();

   respCustomerDailyImports.add(respCustomerDailyImport);

   response.setContentType("application/vnd.ms-excel");

   response.setCharacterEncoding("utf-8");

   // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系

   String fileName = URLEncoder.encode("导出", "UTF-8");

   response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

   EasyExcel.write(response.getOutputStream(), RespCustomerDailyImport.class)

   .sheet("sheet0")

   // 设置字段宽度为自动调整,不太精确

   .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())

   .doWrite(respCustomerDailyImports);

  

 

  导出相关常用API

  ExcelProperty 指定写到第几列,默认根据成员变量排序。value指定写入的名称,默认成员变量的名字。

  ExcelIgnore 默认所有字段都会写入excel,这个注解会忽略这个字段。

  DateTimeFormat 日期转换,将Date写到excel会调用这个注解。里面的value参照java.text.SimpleDateFormat。

  NumberFormat 数字转换,用Number写excel会调用这个注解。里面的value参照java.text.DecimalFormat。

  EasyExcel相关参数

  needHead 监听器是否导出头。

  useDefaultStyle 写的时候是否是使用默认头。

  head 与clazz二选一。写入文件的头列表,建议使用class。

  autoTrim 字符串、表头等数据自动trim。

  sheetNo 需要写入的编码。默认0。

  sheetName 需要些的Sheet名称,默认同sheetNo。

  可以看出不管是excel的读取还是写入,都是一个注解加上一行代码完成,可以让我们少些很多解析的代码,极大减少了重复的工作量。当然这两个例子使用了最简单的方式,EasyExcel还支持更多场景,例如读,可以读多个sheet,也可以解析一行数据或者多行数据做一次入库操作;写的话,支持复杂头,指定列写入,重复多次写入,多个sheet写入,根据模板写入等等。

  近期热文推荐:

  1.1,000+ 道 Java面试题及答案整理(2022最新版)

  2.劲爆!Java 协程要来了。。。

  3.Spring Boot 2.x 教程,太全了!

  4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!

  5.《Java开发手册(嵩山版)》最新发布,速速下载!

  觉得不错,别忘了随手点赞+转发哦!

  以上就是自从用了 EasyExcel,导入导出 Excel 更简单了!(easyexcel导出到指定路径)的详细内容,想要了解更多 自从用了 EasyExcel,导入导出 Excel 更简单了!的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: