EasyExcel的导入与导出及在实际项目生产场景的一下应用例子

本文主要是介绍EasyExcel的导入与导出及在实际项目生产场景的一下应用例子,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

EasyExcel解决数据解析问题

  • 学习目标
  • 学习内容
  • 学习产出
  • 业务描述
  • 业务需求
  • 代码逻辑
  • EasyExcel
    • 导入
    • 导出

学习目标

实际场景业务对文件流进行落库操作
熟练掌握EasyExcel解析Excel文件中的数据并对内容进行解析操作
熟练掌握EasyExcel导出List数据成excel

学习内容

  • EasyExcel 导入
  • EasyExcel 导出

学习产出

  • 完成基本的业务要求

业务描述

通过时间区间去固定的客户号去调用第三方接口,通过返回的Base64文件流对其进行解析,落库操作

页面上对落库的数据进行查询,展示并有导出等一系列业务操作

业务需求

  1. 根据时间区间对数据进行落库,时间区间具体到具体到天,不到时分秒
  2. 落库的数据需要有日志展示并展示每次区间都有对应日志的反补操作
  3. 当前客户第一次数据落库时需要自动落库一年的数据
  4. 当时间区间的数据超过 limit 条时,需要进行二分操作,取时间区间的中间一天,并分成两次请求去获取数据。以此类推,知道数据不超过limit 数量限制。limit数量限制为nacos配置文件中可配置

代码逻辑

1、 触发方法条件,每当客户进行登录操作都去调用条件,并将此次执行配置为一条数据库配置,动态的去选择当前客户是否需求本业务
2、 执行方法,检查当前客户下是否有同步日志,如果有则按最后一次的时间结束为本次的起始时间做增量操作
3、执行方法,如果没有同步日志,则同步近一年的数据
4、获取时间区间的total,判断是否超过limit 没有超过则继续,超过了则拆分时间成两段,轮询这两段时间重新执行改方法。
5、将获取到的文件流落库
6、将生成的日志id作为参数放入队列中
7、利用队列对日志id对应的Base64文件流进行处理

注:当然不会这么简单,但是总体逻辑是这样的,设计具体其他业务,过程比这个复杂的多,无法具体描述

EasyExcel

主要还是需要看官方的需求文档官方文档:官方文档地址

导入

映射的主体必须需要对应上,在主体的Class中在成员变量上添加@ExcelProperty注解,在Class类上添加@ExcelIgnoreUnannotated注解

// 此处是监听器,可以在写个监听器来处理对应sheet里面的数据
InvoiceEasyExcelReadListener invoicelistener = null; 
//读取的逻辑代码
try{// 将base64文件流转为字节byte[] bytes = Base64.decodeBase64(fileBase);// 将字节转为可被easyExcel读取的输入Stream流ByteArrayInputStream bis = new ByteArrayInputStream(bytes);// 将一些需要在业务中处理的mapper,或者参数传入进去,但是在监听器中需要有对应的构造方法invoicelistener = new InvoiceEasyExcelReadListener(mapper0,mapper1,mapper2, 参数);try {/*** read 读取方法 此处的参数为input流,该方法是重载方法。还可以使用其他的读取方法如 readSheet()* excelType方法,读取文件的类型,参数为枚举,官方提供了csv,xls,xlsx三种* sheet读取excel的sheet名字或者下标,此处为固定名字。因为是该excel为固定模板* head 将sheet里面的行数据对应到哪个类对象上* headRowNumber 从第几行开始* registerReadListener 对应的监听器* doRead 执行读取*/EasyExcel.read(bis1).excelType(ExcelTypeEnum.XLSX).sheet("汇总表").head(Invoice.class).headRowNumber(1).registerReadListener(invoiceItemEasyExcelReadListener).doRead();}catch (Exception e2){log.error(incomeId + "读取发票明细信息sheet报错", e2);}
}catch (Exception e) {// 处理失败的逻辑代码log.error("easy错误原因", e);
}

对应的监听器中的处理逻辑

@Component
@Slf4j
public class InvoiceEasyExcelReadListener<T> extends AnalysisEventListener<T> {@Resourceprivate Mapper0 mapper0 ;@Resourceprivate Mapper1 mapper1;@Resourceprivate Mapper2 mapper2;private String 参数;public int success = 0;public int error = 0;private Map<String, Invoice> maps = new HashMap<>();public InvoiceEasyExcelReadListener(Mapper0 mapper0,Mapper1 mapper1,Mapper2 mapper2, String 参数) {this.mapper0 = mapper0 ;this.mapper1= mapper1;this.mapper2= mapper2;this.参数= 参数;}@Overridepublic void invoke(T data, AnalysisContext context) {Invoice invoice = (Invoice) data;//内部处理该行数据的逻辑,如果需要该sheet里面的参数对应可以定义一个map的成员变量,将唯一值作为key,value值根据自己定义//maps.put("key",invoice);// 也可以记录成功的行数与失败的行数 则需要在开头加参数 并且写出对应的get方法try{success++;}catch(Exception e){error++;}}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {log.info("结束");}@Overridepublic boolean hasNext(AnalysisContext context) {return super.hasNext(context);}public int getSuccessNum() {return success;}public int getErrorNum() {return error;}
}

如果需要在外面获取处理结果的数据,直接通过监听器调用里面参数的get方法,例如:

//获取成功的行数
int success = InvoiceEasyExcelReadListener.getSuccessNum();
//获取失败的行数
int error = InvoiceEasyExcelReadListener.getErrorNum();

导出

导出的方式有多种例如自己定义模板,通过映射的实体类转成对应的Excel,@ExcelProperty住注解映射,通过index来确定导出的下标行数,value里面的值对应表头

@ExcelProperty(value = "客户名称",index = 13)
private String custname;

核心介绍:

  • 得到需要转成文件的List数据
  • 导出的文件表头顺序,样式
  • 是否为多sheet
  • 等等

我用的方法里面的大致处理逻辑为:

File file = new File("document_file" + File.separator + fileName);
List<List<String>> dataList = new ArrayList<>();
//里面放需要的参数,按照顺序放入例如  student.getName(),student.getAge()
//第一个sheet
ExcelWriter excelWriter = EasyExcel.write(file).build();
dataList.add(ListUtils.newArrayList(param1,param2...));
//InvoiceExportParam里面是导出映射的实体类,需要用@ExcelIgnoreUnannotated修饰这个类,@ExcelProperty(value = "购方名称",index = 4)这样的格式修饰成员变量
invoiceExport = EasyExcel.writerSheet("主体").head(ExportParam.class).build();
excelWriter.write(dataList,invoiceExport);
//规则同上
WriteSheet invoiceItemExport = EasyExcel.writerSheet("明细").head(ItemExpportParam.class).build();
excelWriter.write(dataListItem,invoiceItemExport);
excelWriter.finish();
// 项目封装的工具栏,将文件转为Base64文件流,最终返回给前端,前端转成blob对象,进行导出下载操作
String fileBase64 = FileUtils.fileToBase64(file);
list.clear();
result.put("code", "0001");
result.put("fileBase", fileBase64);
// 删除临时文件
file.delete();
return result;

我采用的方法为不同的模板使用不同的实体类来对应,感觉有一些不太好的问题,印象中可以将dataList 手动加一行表头,为中文数据,之后再将list依次加入

对于表头第一行的样式,以及内容格式的样式,在官方文档中都有描述,可以去参考官方文档,以下是我设置格式的部分代码

WriteCellStyle headWriteCellStyle = new WriteCellStyle();headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());WriteFont headWriteFont = new WriteFont();headWriteFont.setFontHeightInPoints((short)20);headWriteCellStyle.setWriteFont(headWriteFont);WriteCellStyle contentWriteCellStyle = new WriteCellStyle();WriteFont contentWriteFont = new WriteFont();contentWriteFont.setFontHeightInPoints((short)11);contentWriteCellStyle.setWriteFont(contentWriteFont);HorizontalCellStyleStrategy horizontalCellStyleStrategy =new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

以上代码都是从官方文档中 CV的
完结…

这篇关于EasyExcel的导入与导出及在实际项目生产场景的一下应用例子的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1139807

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

NameNode内存生产配置

Hadoop2.x 系列,配置 NameNode 内存 NameNode 内存默认 2000m ,如果服务器内存 4G , NameNode 内存可以配置 3g 。在 hadoop-env.sh 文件中配置如下。 HADOOP_NAMENODE_OPTS=-Xmx3072m Hadoop3.x 系列,配置 Nam

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#