Java根据excel模版导出Excel(easyexcel、poi)——含项目测试例子拿来即用

Java根据excel模版导出Excel(easyexcel、poi)——含项目测试例子拿来即用

  • 1. 前言
    • 1.1 关于Excel的一般导出
    • 2.2 关于easyexcel的根据模版导出
  • 2. 先看效果
    • 2.1 模版
    • 2.2 效果
  • 3. 代码实现(核心代码)
    • 3.1 项目代码结构
    • 3.2 静态填充例子代码
    • 3.3 动态list填充代码
    • 3.4 附核心代码
      • 3.4.1 object转map工具类
      • 3.4.2 根据模版导出Excel程序代码
      • 3.4.3 导出工具类入口代码
  • 4. 附项目
    • 4.1 一般导出项目代码
    • 4.2 根据模版导出项目代码

1. 前言

1.1 关于Excel的一般导出

  • 一般列表导出以及个性化样式设置请看下面的文章:
    • JAVA导出Excel通用工具类——第一篇:详细介绍POI 导出excel的多种复杂情况,包括动态设置筛选、动态合并横向(纵向)单元格等多种复杂情况.
    • JAVA导出Excel通用工具——第二篇:使用EasyExcel导出excel的多种情况的例子介绍.

2.2 关于easyexcel的根据模版导出

  • 如果使用easy Excel的话,下面就不用看了,这个官网关于怎么使用以及例子提供的非常详细,git上还能下载源码,官网如下,使用不再介绍,具体看官网即可:
    Easy Excel 之 填充excel.

2. 先看效果

2.1 模版

  • 静态填充简单模版如下:
    在这里插入图片描述
  • 动态填充简单模版:
    • 单个list:
      在这里插入图片描述
    • 多个list:
      在这里插入图片描述
    • 单个list单条数据:
      在这里插入图片描述

2.2 效果

  • 静态填充效果如下:
    在这里插入图片描述
  • 动态填充效果如下:
    • 单个list:
      在这里插入图片描述
    • 多个list:
      在这里插入图片描述
    • 单个list单条数据:
      在这里插入图片描述

3. 代码实现(核心代码)

3.1 项目代码结构

  • 如下:
    在这里插入图片描述

3.2 静态填充例子代码

  • 工具类代码已封装,所以调用很简单即可实现,如下:
    在这里插入图片描述

3.3 动态list填充代码

  • 单个list:
    在这里插入图片描述
  • 多个list
    在这里插入图片描述
  • 单个list单条数据:
    在这里插入图片描述

3.4 附核心代码

3.4.1 object转map工具类

  • MapObjectUtil.java 如下:
    package com.liu.susu.excel.template.poi.common;import com.alibaba.fastjson.JSONObject;
    import com.liu.susu.excel.template.poi.example.data.DogEntity2;
    import org.apache.commons.beanutils.BeanMap;import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;/*** @Description* @Author susu* @Date 2024/2/19*/
    public class MapObjectUtil {/*** @description: 将object的list数据 转换成 map的list(如:List<Map<String, Object>>)* @param objDataList* @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>* @author susu*/public static List<Map<String, Object>> objListToMapList(List<?> objDataList){List<Map<String, Object>> dataList = new ArrayList<>();if (objDataList==null || objDataList.size()<1){return null;}objDataList.forEach(obj->{try {Map<String, Object> map = MapObjectUtil.objectToMap(obj);dataList.add(map);} catch (IllegalAccessException e) {throw new RuntimeException(e);}});return dataList;}/*** @description: 将object数据转换成map数据* @param obj* @return java.util.Map<java.lang.String,java.lang.Object>* @author susu*/public static Map<String, Object> objectToMap(Object obj) throws IllegalAccessException {Map<String, Object> map = new HashMap();Class<?> cla = obj.getClass();Field[] fields = cla.getDeclaredFields();for (Field field : fields) {field.setAccessible(true);String keyName = field.getName();Object value = field.get(obj);if (value == null)value = "";map.put(keyName, value);}return map;}/*** @description: 使用 JSONObject 将object转换成map* @param obj* @return java.util.Map<?,?>* @author susu*/public static Map<?, ?> objectToMap2(Object obj) {if (obj == null)return null;return JSONObject.parseObject(JSONObject.toJSONString(obj),Map.class);}/*** @description: 使用BeanMap将object转换成map* @param obj* @return java.util.Map<?,?>* @author susu*/public static Map<?, ?> objectToMap3(Object obj) {if (obj == null)return null;return new BeanMap(obj);}public static void main(String[] args) {DogEntity2 dog = new DogEntity2();dog.setDogId("A-1001");dog.setDogAge(3);dog.setDogName("aaa");
    //        Map map = JSONObject.parseObject(JSONObject.toJSONString(dog),Map.class);Map map = objectToMap2(dog);System.out.println(map);}}
    

3.4.2 根据模版导出Excel程序代码

  • ExcelTemplateProc.java 如下:
    package com.liu.susu.excel.template.poi.common;import org.apache.commons.lang3.StringUtils;
    import org.apache.poi.ss.usermodel.CellCopyPolicy;
    import org.apache.poi.ss.usermodel.Workbook;
    import org.apache.poi.xssf.usermodel.XSSFCell;
    import org.apache.poi.xssf.usermodel.XSSFRow;
    import org.apache.poi.xssf.usermodel.XSSFSheet;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    import org.springframework.util.ResourceUtils;import java.io.*;
    import java.util.List;
    import java.util.Map;/*** @Description 根据模版导出Excel程序* @Author susu* @Date 2024/2/19*/
    public class ExcelTemplateProc {/*** @param templateFileName* @param exportFilePathAndName* @param staticDataMap* @param dynamicDataMappingList* @return void* @description: 根据模版导出Excel入口* @author susu* @date 2024/2/20*/public static void doExportExcelByTemplateProc(String templateFileName, String exportFilePathAndName,Map<String, Object> staticDataMap,List<DynamicDataMapping> dynamicDataMappingList) throws IOException {/*** 1. 从resources下加载模板并替换*    使用 ResourceUtils 加载文件*/File file = ResourceUtils.getFile("classpath:"+templateFileName);InputStream inputStream = new FileInputStream(file);Workbook workbook = dealFirstSheetByTemplate(inputStream, staticDataMap, dynamicDataMappingList);// 2. 保存到本地saveExportFile(workbook, exportFilePathAndName);}/*** @param workbook* @param excelFilePath* @return void* @description: 保存导出的Excel文件到服务器* @author susu* @date 2024/2/20*/public static void saveExportFile(Workbook workbook, String excelFilePath) throws IOException {FileOutputStream outputStream = new FileOutputStream(excelFilePath);executeWorkBookWrite(workbook, outputStream);}/*** @param workbook* @param outputStream* @return void* @description: 数据输出* @author susu* @date 2024/2/20*/public static void executeWorkBookWrite(Workbook workbook, OutputStream outputStream) throws IOException {workbook.write(outputStream);outputStream.flush();outputStream.close();workbook.close();}/*** @param inputStream* @param staticDataMap* @param dynamicDataMappingList* @return org.apache.poi.ss.usermodel.Workbook* @description: 处理只有一个sheet页的模版* @author susu* @date 2024/2/20*/public static Workbook dealFirstSheetByTemplate(InputStream inputStream,Map<String, Object> staticDataMap,List<DynamicDataMapping> dynamicDataMappingList) throws IOException {XSSFWorkbook workbook = new XSSFWorkbook(inputStream);XSSFSheet sheet = workbook.getSheetAt(0);// 按模板处理sheet页dealSheetDataByTemplate(sheet, staticDataMap, dynamicDataMappingList);return workbook;}/*** @param sheet* @param staticDataMap* @param dynamicDataMappingList* @return void* @description: 按模板处理sheet页里的数据* @author susu* @date 2024/2/19*/private static void dealSheetDataByTemplate(XSSFSheet sheet, Map<String, Object> staticDataMap, List<DynamicDataMapping> dynamicDataMappingList) {// 循环sheet里每一行for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {XSSFRow row = sheet.getRow(i);DynamicDataMapping dynamicDataMapping = getDynamicRowDataByMatch(row, dynamicDataMappingList);if (dynamicDataMapping != null) {i = getTemplateLastRowIndexAfterDealTemplate(sheet, i, dynamicDataMapping);} else {dealTemplateDataRow(row, null, staticDataMap);}}}/*** @param row* @param dataMap* @param dataPrefix* @return void* @description: 循环处理模版中每行的数据* @author susu* @date 2024/2/20*/private static void dealTemplateDataRow(XSSFRow row, String dataPrefix, Map<String, Object> dataMap) {if (dataMap == null) {return;}for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {XSSFCell cell = row.getCell(i);fillInTemplateCellDataValue(cell, dataPrefix, dataMap);}}/*** @param cell* @param dataPrefix* @param dataMap* @return void* @description: 填充模版里单元格的值* @author susu* @date 2024/2/20*/private static void fillInTemplateCellDataValue(XSSFCell cell, String dataPrefix, Map<String, Object> dataMap) {if (cell == null) {return;}String cellValue = cell.getStringCellValue();//获取模版里设置的数据if (StringUtils.isEmpty(cellValue)) {return;}boolean flag = false;dataPrefix = StringUtils.isEmpty(dataPrefix) ? "" : (dataPrefix + ".");for (Map.Entry<String, Object> entry : dataMap.entrySet()) {// 循环所有,因为可能一行有多个占位符String cellTemplateStr = "{{" + dataPrefix + entry.getKey() + "}}";if (cellValue.contains(cellTemplateStr)) {// 替换模版中单元格的数据cellValue = cellValue.replace(cellTemplateStr, entry.getValue() == null ? "" : entry.getValue().toString());flag = true;}}if (flag) {cell.setCellValue(cellValue);}}/*** @param row* @param dynamicDataMappingList* @return com.liu.susu.excel.template.poi.common.DynamicDataMapping* @description: 通过模版sheet中的行数据 与 动态数据匹配,获取此行需要填充的动态数据* @author susu* @date 2024/2/21*/private static DynamicDataMapping getDynamicRowDataByMatch(XSSFRow row, List<DynamicDataMapping> dynamicDataMappingList) {if (dynamicDataMappingList == null || dynamicDataMappingList.size() < 1) {return null;}for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {XSSFCell cell = row.getCell(j);String value = cell.getStringCellValue();if (value != null) {for (DynamicDataMapping dynamicData : dynamicDataMappingList) {if (value.startsWith("{{" + dynamicData.getDataId() + ".")) {return dynamicData;}}}}return null;}/*** @param sheet* @param rowIndex* @param dynamicDataMapping* @return int* @description: 根据动态数据的条数动态复制模版行,每处理一个类型的list返回最后的行数,进而处理下一个类型的list* @author susu* @date 2024/2/20*/private static int getTemplateLastRowIndexAfterDealTemplate(XSSFSheet sheet, int rowIndex, DynamicDataMapping dynamicDataMapping) {if (dynamicDataMapping == null) {return rowIndex;}int dataRows = dynamicDataMapping.getDataList().size();// 需要拷贝的行数(因为模板行本身占1行,所以-1)int copyRows = dataRows - 1;if (copyRows > 0) {/*** shiftRows: 从动态数据模版行(rowIndex)到最后一行,这些全部行都向下移copyRows行*            相当于模版行上面插入n行空行(n=copyRows)*/sheet.shiftRows(rowIndex, sheet.getLastRowNum(), copyRows, true, false);// 拷贝策略CellCopyPolicy cellCopyPolicy = makeCellCopyPolicy();// 因为从模版行开始向下平移了copyRows行,所以这里 模板行=rowIndex + copyRows,int templateDataRow = rowIndex + copyRows;// 因为模版行上新增了空行,所以要把模板所在行的模版 拷贝到上面新增的空行for (int i = 0; i < copyRows; i++) {//templateDataRow-模版行数据   rowIndex + i循环的当前空行sheet.copyRows(templateDataRow, templateDataRow, rowIndex + i, cellCopyPolicy);}}// 循环模版行:动态替换模版行(将模版行里的模版替换成动态数据)for (int j = rowIndex; j < rowIndex + dataRows; j++) {Map<String, Object> dataMap = dynamicDataMapping.getDataList().get(j - rowIndex);dealTemplateDataRow(sheet.getRow(j), dynamicDataMapping.getDataId(), dataMap);}return rowIndex + copyRows;}/*** @param* @return org.apache.poi.ss.usermodel.CellCopyPolicy* @description: 拷贝策略* @author susu* @date 2024/2/20*/public static CellCopyPolicy makeCellCopyPolicy() {CellCopyPolicy cellCopyPolicy = new CellCopyPolicy();cellCopyPolicy.setCopyCellValue(true);cellCopyPolicy.setCopyCellStyle(true);return cellCopyPolicy;}}

3.4.3 导出工具类入口代码

  • ExportExcelByTemplateUtils.java 如下:
    package com.liu.susu.excel.template.poi.common;import java.util.HashMap;
    import java.util.List;
    import java.util.Map;/*** @Description 根据模版导出Excel工具类* @Author susu* @Date 2024/2/19*/
    public class ExportExcelByTemplateUtils {/*** @description: 根据模版导出Excel入口(单个list数据)* @param templateFileName* @param exportFilePathAndName* @param staticDataMap* @param dataId* @param originDataList* @return void* @author susu* @date 2024/2/21*/public static void doExportExcelOneListByTemplate(String templateFileName, String exportFilePathAndName,Map<String, Object> staticDataMap,String dataId,List<?> originDataList) throws Exception{List<Map<String, Object>> exportDataList = MapObjectUtil.objListToMapList(originDataList);// 只有一个list数据List<DynamicDataMapping> dynamicDataMappingList = DynamicDataMapping.createOneDataList(dataId, exportDataList);// 导出ExcelTemplateProc.doExportExcelByTemplateProc(templateFileName,exportFilePathAndName,staticDataMap,dynamicDataMappingList);}/*** @description: 根据模版导出Excel入口(多个list数据)* @param templateFileName* @param exportFilePathAndName* @param staticSource* @param originDataMapList* @return void* @author susu* @date 2024/2/20*/public static void doExportExcelMoreListByTemplate(String templateFileName,String exportFilePathAndName,Map<String, Object> staticSource,Map<String, List<?>> originDataMapList) throws Exception{Map<String,List<Map<String, Object>>> transMap = new HashMap<>();originDataMapList.forEach((dataId,originDataList)->{List<Map<String, Object>> transDataList = MapObjectUtil.objListToMapList(originDataList);transMap.put(dataId,transDataList);});// 多个list类型数据List<DynamicDataMapping> dynamicDataMappingList = DynamicDataMapping.createMorDataList(transMap);// 导出ExcelTemplateProc.doExportExcelByTemplateProc(templateFileName,exportFilePathAndName,staticSource,dynamicDataMappingList);}}
    

4. 附项目

4.1 一般导出项目代码

  • 如下:
    Java导出excel工具详细介绍(POI 和 EasyExcel),各种复杂需求情况的导出(包括动态设置合并单元格等).

4.2 根据模版导出项目代码

  • 如下:
    Java根据自定义模版导出各种需求的Excel(使用POI).

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

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

相关文章

Rabbitmq 超时异常解决:PRECONDITION_FAILED - Timeout value used: 1800000 ms.

Rabbitmq 超时异常解决&#xff1a;PRECONDITION_FAILED - Timeout value used: 1800000 ms. 在使用 docker 启动 rabbitmq 的时候&#xff0c;执行一个超长时间的任务&#xff0c;出现了报错。 查询了一下发现&#xff0c;这个问题在于 rabbitmq 默认客户端超时时间是30分钟,…

python 基础语法及保留字

编码 默认情况下&#xff0c;Python 3 源码文件以 UTF-8 编码&#xff0c;所有字符串都是 unicode 字符串。 当然你也可以为源码文件指定不同的编码&#xff1a; # -*- coding: cp-1252 -*-上述定义允许在源文件中使用 Windows-1252 字符集中的字符编码&#xff0c;对应适合语…

《高考》期刊杂志投稿邮箱知网教育类期刊发表

《高考》杂志是由国家新闻出版总署批准的正规教育类期刊。主要宣传高中新课程改革的专业性&#xff0c;是教育管理工作者、高中一线教师交流经验、探讨问题的重要平台&#xff0c;期刊突出政策性、针对性、指导性&#xff0c;是一本以教育科研成果展示为主&#xff0c;兼具教育…

x86使用GDT表实现系统调用--用户调用系统功能

系统调用 视频讲解可以看这一个课程 GDT表相关知识 原理 注册 允许应用调用操作系统的一些函数, 主要是由于权限, 需要在特区级下面运行一些操作 页表相关设置的时候有一个设置是PDE_U位, 这时候用户就可以访问这一段地址, 否则就是需要系统操作级来进行操作 实现系统调用…

xss-跨站脚本攻击漏洞

前备知识&#xff1a; Cookie和Session是Web开发中用于维持用户状态、跟踪用户会话的核心技术&#xff0c;它们的主要目的是在无状态的HTTP协议基础上实现有状态的用户交互。 **Cookie**&#xff1a; - Cookie是一种由服务器发送到客户端&#xff08;通常是用户的浏览器&#x…

OpenAI视频生成Sora技术简析

基本介绍 Sora是春节期间OpenAI发布的产品&#xff0c;主要是通过文字描述生成视频&#xff0c;通过大规模视频数据训练而成的生成模型&#xff0c;当前还没开放试用。官方发布的技术报告&#xff1a;https://openai.com/research/video-generation-models-as-world-simulators…

无线综合测试仪8960(E5515C)

无线综合测试仪8960&#xff08;E5515C&#xff09; 简述&#xff1a; 8960是美国安捷伦&#xff08;Agilent&#xff09;公司生产的手机综测仪&#xff0c;8960测试仪是一款E5515C主机&#xff0c;具有特定于技术的硬件选件和软件应用程序。有两个硬件选项&#xff0c;8960能…

SpringBoot 学习笔记

文章目录 一、IoC二、AOP三、bean3.1 bean 生命周期3.2 三种依赖注入方式3.3 bean 线程安全 四、SpringMVC五、常用注解5.1 Scope5.2 PostConstruct 和 PreDestroy5.3 Component 和 Bean5.4 Autowired 和 Resource 六、基于 ApplicationContextAware 实现工厂模式七、事务失效八…

阿里巴巴alibaba API商品详情接口系列(商品属性,价格,主图)阿里巴巴alibaba根据ID取商品详情 API 返回值说明

阿里巴巴Alibaba的API商品详情接口系列通常用于获取指定商品的详细信息&#xff0c;包括商品属性、价格、主图等。与来赞达Lazada的API类似&#xff0c;具体的返回值可能会根据API的版本和阿里巴巴平台的更新而有所不同。 以下是一个假设的阿里巴巴API商品详情接口的返回值示例…

[AutoSar]BSW_Com03 DBC详解 (一)

目录 关键词平台说明一、DBC 定义1.1 相关工具 二、主要组成部分介绍2.1 Networks2.2 ECUs2.3 Network nodes2.4 messages2.5 signal2.6 Value Tables 三、主要组成部分关系图 关键词 嵌入式、C语言、autosar、OS、BSW 平台说明 项目ValueOSautosar OSautosar厂商vector &am…

react项目引入electron进行mac、windows桌面应用打包,通过浏览器下载安装包

打包步骤 全局安装electron npm install electron -g在react项目的根目录中&#xff0c;创建一个新的文件夹electron&#xff0c;用于存放electron相关的文件在该文件夹中&#xff0c;创建一个新的package.json文件&#xff0c;并添加以下内容&#xff1a; {"name"…

推荐一个 Obsidian 的 ChatGPT 插件

源码地址&#xff1a;https://github.com/nhaouari/obsidian-textgenerator-plugin Text Generator 是目前我使用过的最好的 Obsidian 中的 ChatGPT 功能插件。它旨在智能生成内容&#xff0c;以便轻松记笔记。它不仅可以在 Obsidian 中直接使用 ChatGPT&#xff0c;还提供了优…

二叉树高频题目(不含树形DP)

二叉树高频题 二叉树的层序遍历 . - 力扣&#xff08;LeetCode&#xff09; 按点弹出 class Solution { public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>>ans;if(root!nullptr){queue<TreeNode*>q;unordered_map&…

音视频技术-电脑连接调音台时交流声的产生与消除

当电脑&#xff08;笔记本/台式机&#xff09;声卡通过音频线与调音台&#xff08;或扩音机&#xff09;连接时&#xff0c;能听到“交流声”。有时很轻微&#xff0c;有时很明显&#xff0c;甚至干扰正常的演讲或发言。 很多时候&#xff0c;我们在台上演讲时&#xff0c;都会…

Centos7.9环境源码编译安装ffmpeg6.x

1.官网ffmpeg下载源码 https://ffmpeg.org/download.html#build-windows 2.未安装x264库则先安装配置 可以先查询x264库: whereis libx264 安装编译工具和依赖库&#xff1a; sudo yum install gcc make cmake mercurial git yasm pkgconfig autoconf automake libtool sudo…

UE4 材质多张图片拼接成一张图片(此处用2×2拼接)

UE4 材质多张图片拼接成一张图片&#xff08;此处用22拼接&#xff09; //TexCoord,TextureA,TextureB,TextureC,TextureDfloat3 ReturnTexture TextureA; if(TexCoord.x < 0.5 && TexCoord.y < 0.5) {ReturnTexture TextureA; } else if(TexCoord.x > 0.5…

力扣1290. 二进制链表转整数

Problem: 1290. 二进制链表转整数 文章目录 题目描述思路复杂度Code 题目描述 思路 1.记录一个变量res初始化为0&#xff0c;指针p指向链表头&#xff1b; 2.循环每次res res * 2 p -> val;p p -> next;&#xff08;充分利用二进制数的特性&#xff1b;其中利用指针先…

C++前言..

1.前言 C主要从三个模块讲起 分别是&#xff1a;语法(包括底层汇编)、面向对象以及项目实战 C语言纯面向过程 而Java纯面向对象 但是C则是一门面向过程和面向对象都较为完善的语言 并且他能做到Java所不能做到的点就是他更能够窥探底层的汇编代码 而Java是一点都不想透露给外…

leetcode初级算法(python)- 字符串

文章目录 1.反转字符串常规算法pythonic 算法2.整数反转数学法字符串法3.字符串中的第一个唯一字符pythonic算法哈希算法4.有效的字母异位词常规算法进阶算法5.最长公共前缀1.反转字符串 输入:[‘h’,‘e’,‘l’,‘l’,‘o’] 输出:[‘o’,‘l’,‘l’,‘e’,‘h’]

LeetCode 第三题: 无重复字符的最长子串

文章目录 题目描述示例 解题思路 - 滑动窗口法Go语言实现 - 滑动窗口法算法分析 解题思路 - 优化的滑动窗口法 题目描述 给定一个字符串&#xff0c;请你找出其中不含有重复字符的最长子串的长度。 示例 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串…