EasyExcel读模板生成excel文件注解Bean生成文件

文章目录

  • 1、EasyExce依赖准备
  • 2、通过注解Bean的方式生成Excel
    • 2.1、注解Bean准备
    • 2.2、封装数据,生成Excel(只需要几行代码)
      • 2.3、生成结果展示
  • 3、通过Excel模板生成数据
    • 3.1、准备编写Excel模板
    • 3.2、封装数据,生成excel
    • 3.3、模板导出数据结果展示
  • 附录
    • 占位符为什么是`{.字段名}`?源码分析
    • 参考链接

1、EasyExce依赖准备

  1. EasyExcel依赖
    <!-- easyexcel: excel快速导出--><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.0</version></dependency>
  1. apache poi依赖

        EasyExcel同时依赖Apache POI库,同时还需要注意下两个库的版本对应关系。EasyExcel可能升级对poi的依赖,导致功能不兼容。

    <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.2</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.2</version></dependency>

2、通过注解Bean的方式生成Excel

2.1、注解Bean准备

EasyExcel注解部分参考:EasyExcel注解大全_起一个让人印象深刻的名字的博客-CSDN博客

package com.dongzi.utils.excel.bean;import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.write.style.*;
import com.alibaba.excel.enums.BooleanEnum;
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
import com.alibaba.excel.enums.poi.VerticalAlignmentEnum;
import lombok.Data;
import lombok.experimental.Accessors;import java.util.Date;@Data // lombok提供getter\setter等
@Accessors(chain = true) // lombok提供链式操作
@ContentRowHeight(25) // 行高
public class FillData {@HeadStyle(fillBackgroundColor = 4) // 表头样式设置,背景颜色填充,颜色类型4@HeadFontStyle(fontName = "宋体", fontHeightInPoints = 25, color = 3) // 表头字体设置,宋体,颜色3@ExcelProperty(value = "姓名") // 列名@ColumnWidth(20) // 列宽@ContentFontStyle(fontName = "宋体", color = 4, bold = BooleanEnum.TRUE) // 数据部分单元格字体样式@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER)// 数据部分单元格样式private String name; // 字段@HeadStyle(fillBackgroundColor = 4)@HeadFontStyle(fontName = "楷体", fontHeightInPoints = 25, color = 3)@ExcelProperty(value = "地址")@ColumnWidth(20)@ContentFontStyle(fontName = "楷体")@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER)private String address;@HeadStyle(fillBackgroundColor = 4)@HeadFontStyle(fontName = "微软雅黑", fontHeightInPoints = 25, color = 3)@ExcelProperty(value = "时间")@ColumnWidth(50)@ContentFontStyle(fontName = "微软雅黑")@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER)@DateTimeFormat(value = "yyyy-MM-dd") // 时间格式化private Date date;// 忽略生成的字段@ExcelIgnoreprivate String welcome;}

2.2、封装数据,生成Excel(只需要几行代码)

package com.dongzi.utils.excel;import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.dongzi.utils.excel.bean.FillData;
import org.springframework.core.io.ClassPathResource;import java.io.File;
import java.io.IOException;
import java.util.*;public class ReadeExcelTemplate {public static void main(String[] args) throws IOException {exportDataByAnnotation();}// 基于注解导出数据public static void exportDataByAnnotation() {// 文件输出位置File outPutFile = new File("D:/temp/Excel-基于注解导出数据.xlsx");// 指定使用哪个注解Bean来生成Excel?ExcelWriter excelWriter = EasyExcel.write(outPutFile, FillData.class).excelType(ExcelTypeEnum.XLSX).build();// 生成数据excelWriter.write(fillData(5), EasyExcelFactory.writerSheet(0).build());// 完成,写数据到本地excelWriter.finish();}public static List<FillData> fillData(int num) {List<FillData> mapList = new ArrayList<>();for (int i = 0; i < num; i++) {FillData fillData = new FillData();fillData.setName("姓名" + i).setAddress("住址" + i).setWelcome("你好" + i).setDate(new Date());mapList.add(fillData);}return mapList;}
}

2.3、生成结果展示

image.png

3、通过Excel模板生成数据

3.1、准备编写Excel模板

注意!

  1. 占位符的书写格式为{.字段名}(为什么占位符是这样的,详见附录)
  2. 一个单元格个可以写多个占位符
  3. 模板需要按照预定的格式/样式调整好,之后会按照相同格式输出单元格
  4. 数据输出视占位符所在位置依次向下输出

如图:Sheet1模板
image.png
如图:Sheet2模板
image.png
如图:Sheet3模板
image.png

3.2、封装数据,生成excel

package com.dongzi.utils.excel;import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.dongzi.utils.excel.bean.FillData;
import org.springframework.core.io.ClassPathResource;import java.io.File;
import java.io.IOException;
import java.util.*;public class ReadeExcelTemplate {public static void main(String[] args) throws IOException {exportDataByTemplate();}// 基于excel模板导出数据public static void exportDataByTemplate() throws IOException {File outPutFile = new File("D:/temp/Excel-基于模板导出数据.xlsx");ClassPathResource pathResource = new ClassPathResource("template/info.xlsx");// 基于excel模板导出数据ExcelWriter excelWriter = EasyExcel.write(outPutFile).withTemplate(pathResource.getInputStream()).excelType(ExcelTypeEnum.XLSX).build();//        excelWriter.write(fillData(5), EasyExcel.writerSheet(0).build());
//        excelWriter.write(fillData(10), EasyExcel.writerSheet(1).build());
//        excelWriter.write(fillData(15), EasyExcel.writerSheet(2).build());// {.name}-{.welcome}, {.address}, {.date} 占位符位置数据补充,一个单元格可以写多个{.字段名}// 数据的位置从当前sheet页的的占位符位置开始,无论title在什么位置// 注意这里必须使用excelWriter.fill()进行数据填充excelWriter.fill(fillData(5), EasyExcel.writerSheet(0).build());excelWriter.fill(fillData(10), EasyExcel.writerSheet(1).build());excelWriter.fill(fillData(15), EasyExcelFactory.writerSheet(2).build());// {.name}, {.address}, {.date} 占位符位置数据补充
//        excelWriter.fill(fillData2(5), EasyExcel.writerSheet(0).build());
//        excelWriter.fill(fillData2(10), EasyExcel.writerSheet(1).build());
//        excelWriter.fill(fillData2(15), EasyExcelFactory.writerSheet(2).build());excelWriter.finish();}public static List<Map<String, Object>> fillData2(int num) {List<Map<String, Object>> mapList = new ArrayList<>();for (int i = 0; i < num; i++) {Map<String, Object> beanMap = new HashMap<>();beanMap.put("name", "姓名" + i);beanMap.put("welcome", "你好" + i);beanMap.put("address", "地址" + i);beanMap.put("date", DateUtil.format(new Date(), "yyyy-MM-dd"));mapList.add(beanMap);}return mapList;}
}

3.3、模板导出数据结果展示

如图:Sheet1,中间框,加边框
image.png
如图:Sheet2,第三列加边框
image.png
如图:Sheet3,数据随着占位符的位置向下生成
image.png

附录

占位符为什么是{.字段名}?源码分析

excelWriter.fill()逐行调试,发现:在读excel模板的时候,会先进行占位符的解析。看源码:
包路径: package com.alibaba.excel.write.executor;

 private List<AnalysisCell> readTemplateData(Map<ExcelWriteFillExecutor.UniqueDataFlagKey, List<AnalysisCell>> analysisCache) {List<AnalysisCell> analysisCellList = (List)analysisCache.get(this.currentUniqueDataFlag);if (analysisCellList != null) {return analysisCellList;} else {Sheet sheet = this.writeContext.writeSheetHolder().getCachedSheet();Map<ExcelWriteFillExecutor.UniqueDataFlagKey, Set<Integer>> firstRowCache = MapUtils.newHashMapWithExpectedSize(8);for(int i = 0; i <= sheet.getLastRowNum(); ++i) {Row row = sheet.getRow(i);if (row != null) {for(int j = 0; j < row.getLastCellNum(); ++j) {Cell cell = row.getCell(j);if (cell != null) {// 解析单元格占位符String preparedData = this.prepareData(cell, i, j, firstRowCache);if (preparedData != null) {cell.setCellValue(preparedData);}}}}}return (List)analysisCache.get(this.currentUniqueDataFlag);}}private String prepareData(Cell cell, int rowIndex, int columnIndex, Map<ExcelWriteFillExecutor.UniqueDataFlagKey, Set<Integer>> firstRowCache) {if (!CellType.STRING.equals(cell.getCellType())) {return null;} else {String value = cell.getStringCellValue();if (StringUtils.isEmpty(value)) {return null;} else {StringBuilder preparedData = new StringBuilder();AnalysisCell analysisCell = null;int startIndex = 0;int length = value.length();int lastPrepareDataIndex = 0;label81:while(startIndex < length) {// 对单元格占位符进行分割,取出字段名,之后按字段名去取值// 有兴趣的可以逐行调试int prefixIndex = value.indexOf("{", startIndex);if (prefixIndex < 0) {break;}if (prefixIndex != 0) {char prefixPrefixChar = value.charAt(prefixIndex - 1);if (prefixPrefixChar == '\\') {startIndex = prefixIndex + 1;continue;}}int suffixIndex = -1;while(suffixIndex == -1 && startIndex < length) {suffixIndex = value.indexOf("}", startIndex + 1);if (suffixIndex < 0) {break label81;}startIndex = suffixIndex + 1;char prefixSuffixChar = value.charAt(suffixIndex - 1);if (prefixSuffixChar == '\\') {suffixIndex = -1;}}if (analysisCell == null) {analysisCell = this.initAnalysisCell(rowIndex, columnIndex);}String variable = value.substring(prefixIndex + 1, suffixIndex);if (!StringUtils.isEmpty(variable)) {int collectPrefixIndex = variable.indexOf(".");if (collectPrefixIndex > -1) {if (collectPrefixIndex != 0) {analysisCell.setPrefix(variable.substring(0, collectPrefixIndex));}variable = variable.substring(collectPrefixIndex + 1);if (StringUtils.isEmpty(variable)) {continue;}analysisCell.setCellType(WriteTemplateAnalysisCellTypeEnum.COLLECTION);}analysisCell.getVariableList().add(variable);if (lastPrepareDataIndex == prefixIndex) {analysisCell.getPrepareDataList().add("");if (lastPrepareDataIndex != 0) {analysisCell.setOnlyOneVariable(Boolean.FALSE);}} else {String data = this.convertPrepareData(value.substring(lastPrepareDataIndex, prefixIndex));preparedData.append(data);analysisCell.getPrepareDataList().add(data);analysisCell.setOnlyOneVariable(Boolean.FALSE);}lastPrepareDataIndex = suffixIndex + 1;}}if (analysisCell != null && CollectionUtils.isNotEmpty(analysisCell.getVariableList())) {cell.setBlank();}return this.dealAnalysisCell(analysisCell, value, rowIndex, lastPrepareDataIndex, length, firstRowCache, preparedData);}}}

参考链接

EasyExcel读取模板填充数据_easyexcel填充模板_hello_cmy的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/66380.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

stm32之28.ADC

须看原理图&#xff08;引脚、电压值、ADC几号通道&#xff09;配置 。 若对比值0~4096 模拟电压/参考电压4096/x 假设模拟电压2.1V&#xff0c;参考电压3.3v&#xff0c;4096/x3.3/2.1 ->3.3x2.1x4096 ->x2,606.5 也可反推出模拟电压 ADC转换时间 ADC时钟来源于…

JavaScript -【第二周】

文章来源于网上收集和自己原创&#xff0c;若侵害到您的权利&#xff0c;请您及时联系并删除~~~ 理解什么是流程控制&#xff0c;知道条件控制的种类并掌握其对应的语法规则&#xff0c;具备利用循环编写简易ATM取款机程序能力 运算符语句综合案例 1. 运算符 算术运算符赋值运…

SAP_ABAP_接口技术_RFC远程函数实践总结

SAP ABAP顾问能力模型梳理_企业数字化建设者的博客-CSDN博客SAP Abap顾问能力模型&#xff0c;ALV/REPORT|SMARTFROM|SCREEN|OLE|BAPI|BDC|PI|IDOC|RFC|API|WEBSERVICE|Enhancement|UserExits|Badi|Debughttps://blog.csdn.net/java_zhong1990/article/details/132469977 SAP接…

docker安装jenkins

运行jenkins docker run -d \--name jenkins \ --hostname jenkins \-u root \-p 29090:8080 \--restart always \-v D:\springcloud\学习\jekins\jenkins\jks_home:/var/jenkins_home \ jenkins/jenkins获取root登录密码 密码在jekins_home/secrets/initalAdminPassword文件…

设计模式-观察者模式

文章目录 一、前言二、观察者模式1、基本概念2、应用举例3、结构3.1、Observer和ConcreteObserver3.2、Subject和ConcreteSubject 4、代码展示4.1、主题接口 WeatherData 和观察者接口 Observer4.2、具体主题 WeatherStation&#xff0c;它实现了 WeatherData 接口&#xff1a;…

【Spring+SpringMVC+Mybatis】SSM框架的整合、思想、工作原理和优缺点的略微讲解

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;目前学习C/C、算法、Python、Java等方向&#xff0c;一个正在慢慢前行的普通人。 &#x1f3c0;系列专栏&#xff1a;陈童学的日记 &#x1f4a1;其他专栏&#xff1a;CSTL&…

软件产品鉴定测试

1. 服务流程 2. 服务内容 该项测试从技术和应用的角度对商用软件产品的质量特性进行全面地、系统地测试和评估&#xff0c;测试内容涵盖了功能性测试、性能测试、可靠性测试、易用性测试、维护性测试及可移植性测试。 3. 周期 7-15个工作日 4. 报告用途 可作为进行省级、国…

苹果启动2024年SRDP计划:邀请安全专家使用定制iPhone寻找漏洞

苹果公司昨天&#xff08;8月30日&#xff09;正式宣布开始接受2024 年iPhone安全研究设备计划的申请&#xff0c;iOS 安全研究人员可以在 10 月底之前申请安全研究设备 SRD。 SRD设备是专门向安全研究人员提供的iPhone14Pro&#xff0c;该设备具有专为安全研究而设计的特殊硬…

leetcode622-设计循环队列

本题重点&#xff1a; 1. 选择合适的数据结构 2. 针对选择的数据结构判断“空”和“满” 这两点是不分先后次序的&#xff0c;在思考时应该被综合起来。事实上&#xff0c;无论我们选择链表还是数组&#xff0c;最终都能实现题中描述的“循环队列”的功能&#xff0c;只不过…

vscode远程调试php

使用vscode远程调试php的方法 1.安装remote ssh插件 2.连接服务器 可以点击左下角的绿色按钮&#xff0c;或者ctrlshiftp打开命令框输入remote ssh应该也有。 3.在服务器端vscode安装php debug插件 4.安装xdebug xdebug是用来调试php的软件&#xff0c;原本和vscode没什么关…

iBooker 技术评论 20230831

一、轻资产项目的五类分类 轻资产项目不需要投资&#xff0c;但也不是所有人都做得了&#xff0c;取决于个人认知和能力水平限制。 就好比以前的各科题目&#xff0c;你也不是都能做吧&#xff1f; 我以前刷题的时候&#xff0c;喜欢把题目按照难易程度分五类。现在做项目和…

人工智能研究的未来:20 年机器学习和深度学习的论文创意!

“机器学习的美妙之处在于&#xff0c;它可以应用于你想要解决的任何问题&#xff0c;只要你能为计算机提供足够的例子。” 一、说明 该文章列出了 20 年机器学习和深度学习本科课程的 2023 个潜在论文想法。每个论文的想法都包括一个介绍&#xff0c;简要概述了主题和研究目标…

明厨亮灶监控实施方案 opencv

明厨亮灶监控实施方案通过pythonopencv网络模型图像识别算法&#xff0c;一旦发现现场人员没有正确佩戴厨师帽或厨师服&#xff0c;及时发现明火离岗、不戴口罩、厨房抽烟、老鼠出没以及陌生人进入后厨等问题生成告警信息并进行提示。OpenCV是一个基于Apache2.0许可&#xff08…

【Ubuntu】解决ubuntu虚拟机和物理机之间复制粘贴问题(无需桌面工具)

解决Ubuntu虚拟机和物理机之间复制粘贴问题 第一步 先删除原来的vmware tools&#xff08;如果有的话&#xff09; sudo apt-get autoremove open-vm-tools第二步 安装软件包&#xff0c;一般都是用的desktop版本&#xff08;如果是server换一下&#xff09; sudo apt-get …

计算机视觉的应用12-卷积神经网络中图像特征提取的可视化研究,让大家理解特征提取的全过程

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用12-卷积神经网络中图像特征提取的可视化研究&#xff0c;让大家理解特征提取的全过程。 要理解卷积神经网络中图像特征提取的全过程&#xff0c;我们可以将其比喻为人脑对视觉信息的处理过程。就像…

FC-CLIP-卷积永存:开放词汇分割与单一冻结卷积CLIP

论文链接&#xff1a;https://arxiv.org/abs/2308.02487 Github&#xff1a;GitHub - bytedance/fc-clip: This repo contains the code for our paper Convolutions Die Hard: Open-Vocabulary Segmentation with Single Frozen Convolutional CLIP 机构&#xff1a;约翰霍普…

基于Java的OA办公管理系统,Spring Boot框架,vue技术,mysql数据库,前台+后台,完美运行,有一万一千字论文。

基于Java的OA办公管理系统&#xff0c;Spring Boot框架&#xff0c;vue技术&#xff0c;mysql数据库&#xff0c;前台后台&#xff0c;完美运行&#xff0c;有一万一千字论文。 系统中的功能模块主要是实现管理员和员工的管理&#xff1b; 管理员&#xff1a;个人中心、普通员工…

C++中的语法知识虚继承和虚基类

多继承(Multiple Inheritance)是指从多个直接基类中产生派生类的能力,多继承的派生类继承了所有父类的成员。尽管概念上非常简单,但是多个基类的相互交织可能会带来错综复杂的设计问题,命名冲突就是不可回避的一个。 多继承时很容易产生命名冲突,即使我们很小心地将所有类…

PQUEUE - Printer Queue

题目描述 The only printer in the computer science students union is experiencing an extremely heavy workload. Sometimes there are a hundred jobs in the printer queue and you may have to wait for hours to get a single page of output. Because some jobs are …

【GoldenDict】win11牛津高阶英汉双解词典安装使用方法

【词典资源】 1&#xff08;本文章使用的版本&#xff09;牛津高阶&#xff08;第10版 英汉双解&#xff09; V11.8&#xff1a; https://pan.baidu.com/s/11272Cldde_2UttQkWS2MlQ 提取码&#xff1a;0p3j 2&#xff08;另一版本&#xff09;第十版 v13.2&#xff1a; ht…