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

news/2024/5/21 5:25:59/文章来源:https://blog.csdn.net/suixinfeixiangfei/article/details/136295131

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.luyixian.cn/news_show_988118.aspx

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

相关文章

Springboot项目中定时任务的四种实现方式

文章目录 1. 使用Scheduled注解1.1 时间间隔执行1.2 固定时间点执行 2. 使用EnableScheduling注解启用定时任务3. 实现SchedulingConfigurer接口4. 使用Quartz框架4.1 配置QuartzScheduler4.2 定义Job类和Trigger类 5. 总结 在开发现代应用时&#xff0c;定时任务是一个非常常见…

Peter算法小课堂—动态规划

Peter来啦&#xff0c;好久没有更新了呢 今天&#xff0c;我们来讨论讨论提高组的动态规划。 动态规划 动态规划有好多经典的题&#xff0c;有什么背包问题、正整数拆分、杨辉三角……但是&#xff0c;如果考到陌生的题&#xff0c;怎么办呢&#xff1f;比如说2000年提高组的…

压缩视频大小的软件有哪些?5款软件推荐

压缩视频大小的软件有哪些&#xff1f;随着高清摄像设备的普及和网络速度的不断提升&#xff0c;视频文件变得越来越庞大&#xff0c;动辄数百兆甚至数GB的大小常常让用户在分享和存储时感到头疼。幸运的是&#xff0c;市面上有许多优秀的视频压缩软件可以帮助我们轻松应对这一…

国产服务器操作系统

为何记录 最近的开发工作经常接触到国产服务器操作系统的业务&#xff0c;经常被x86、arm、龙芯、鲲鹏、欧拉...搞得一脸懵逼&#xff0c;遂记之&#xff01; 操作系统 这里按照应用场景分&#xff1a; 桌面操作系统&#xff1a;主要用于pc&#xff0c;如Windows、macOS、Li…

SpringMVC01、回顾MVC

1、回顾MVC 1.1、什么是MVC MVC是模型(Model)、视图(View)、控制器(Controller)的简写&#xff0c;是一种软件设计规范。是将业务逻辑、数据、显示分离的方法来组织代码。MVC主要作用是降低了视图与业务逻辑间的双向偶合。MVC不是一种设计模式&#xff0c;MVC是一种架构模式。…

ETL数据仓库的使用方式

一、ETL的过程 在 ETL 过程中&#xff0c;数据从源系统中抽取&#xff08;Extract&#xff09;&#xff0c;经过各种转换&#xff08;Transform&#xff09;操作&#xff0c;最后加载&#xff08;Load&#xff09;到目标数据仓库中。以下是 ETL 数仓流程的基本步骤&#xff1a…

【物联网应用案例】智能农业的 9 个技术用例

一、农业中的物联网用例 一般而言&#xff0c;农业物联网传感器以及农业物联网应用有多种类型&#xff1a; 1. 气候条件监测 气象站无疑是当今智能农业领域最受欢迎的设备。这款设备集成了多种智能农业传感器&#xff0c;能够在现场对各类数据进行收集&#xff0c;然后迅速将…

动态规划--(算法竞赛、蓝桥杯)--二维费用背包

1、B站视频链接&#xff1a;E15 背包DP 二维费用背包_哔哩哔哩_bilibili #include <bits/stdc.h> using namespace std; int f[101][101]; //f[j][k]第i件物品&#xff0c;体积<j,重量<k的最大价值int main(){int n,V,W;//物品、容量、承重int v,w,val;//体积、重…

搜索算法(算法竞赛、蓝桥杯)--DFS迭代加深

1、B站视频链接&#xff1a;B25 迭代加深 Addition Chains_哔哩哔哩_bilibili 题目链接&#xff1a;Addition Chains - 洛谷 #include <bits/stdc.h> using namespace std; int n,d;//d为搜索的深度 int a[10005];//存储加成的序列bool dfs(int u){//搜索第u层 if(ud)r…

应急响应-常规处置办法

网站中被植入Webshell&#xff0c;通常代表着网站中存在可利用的高危漏洞&#xff0c;攻击者利用这些漏洞&#xff0c;将Webshell写入网站&#xff0c;从而获取网站的控制权。一旦在网站中发现webshell文件&#xff0c;可采取以下步骤进行临时处置。 入侵确定时间 通过在网站…

frp 内网穿透 linux部署版

frp 内网穿透 linux部署版 前提安装 frp阿里云服务器配置测试服务器配置访问公网 前提 使用 frp&#xff0c;您可以安全、便捷地将内网服务暴露到公网&#xff0c;通过访问公网 IP 直接可以访问到内网的测试环境。准备如下&#xff1a; 公网 IP已部署好的测试服务 IP:端口号阿…

浅谈排序算法(冒泡,插入,归并)

对于数据的排序&#xff0c;有多种方法&#xff0c;对应这不同的时间复杂度&#xff08;效率不同&#xff09;。 ​一、冒泡排序&#xff08;Bubble Sort&#xff09; 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的排序算法。 算法思路&#xff1a; 1. 从第一对相…

3月5日济南,2024生物发酵展全新起航!助力打造生物产业经济新时代

生物发酵是生物产业的重要组成部分&#xff0c;近年来&#xff0c;我国生物产业发展迅猛&#xff0c;也已广泛应用于食品、农业、医药、饲料、日化、材料等领域&#xff0c;市场前景广阔。2022年5月&#xff0c;国家发改委发布的《“十四五”生物经济发展规划》明确着力做大做强…

“图像处理新篇章,轻松切割纵向长图,每张都精彩!

在数字化时代&#xff0c;图像处理技术日新月异&#xff0c;人们对图片质量的要求也越来越高。为满足这一需求&#xff0c;新一代图像处理技术应运而生&#xff0c;它以其独特的功能和卓越的效果&#xff0c;为用户带来了前所未有的体验。今天&#xff0c;就让我们一起领略这项…

ImportError: cannot import name ‘_update_worker_pids’ from ‘torch._C’

问题描述&#xff1a; 在复现超分辨率算法RNAN&#xff08;EDSR、RCAN同样的环境&#xff09;的时候报错&#xff0c;torch要求是0.4.0版本的。 解决方案&#xff1a; 解决方法1&#xff08;已安装anaconda&#xff09; 1. 打开命令行&#xff08;这个自行查找&#xff09; …

基于 ECharts的Python 数据可视化库,它允许用户使用 Python 语言生成各种类型的交互式图表和数据可视化

pyecharts 是一个基于 ECharts 的 Python 数据可视化库&#xff0c;它允许用户使用 Python 语言生成各种类型的交互式图表和数据可视化。 ECharts 是由百度开发的一款强大的开源数据可视化库&#xff0c;而 Pyecharts 则是 ECharts 的 Python 封装&#xff0c;使得在 Python 中…

SpringMVC02、什么是SpringMVC

2、什么是SpringMVC 2.1、概述 Spring MVC是Spring Framework的一部分&#xff0c;是基于Java实现MVC的轻量级Web框架。 查看官方文档&#xff1a;Web on Servlet Stack 我们为什么要学习SpringMVC呢? Spring MVC的特点&#xff1a; 轻量级&#xff0c;简单易学高效 , 基…

2024全国水科技大会暨高氨氮废水厌氧氨氧化处理技术论坛(四)

一、会议背景 为积极应对“十四五”期间我国生态环境治理面临的挑战&#xff0c;加快生态环境科技创新&#xff0c;构建绿色技术创新体系&#xff0c;全面落实科学技术部、生态环境部等部委编制的《“十四五”生态环境领域科技创新专项规划》&#xff0c;积极落实省校合作&…

1.1 编写第一个C程序

1.1 编写第一个C程序 在这一节中&#xff0c;我们将介绍如何编写、编译和执行一个简单的C程序。我们将从一个"Hello, World!"程序开始&#xff0c;这是学习任何编程语言时的传统。 1.1.1 创建C源文件 首先&#xff0c;使用任何文本编辑器&#xff08;如Notepad、V…

阿里云降价!云数据库277元一年,价格下调折扣对照表

2024年阿里云百款产品直降&#xff0c;平均降幅20%&#xff0c;不只是云服务器&#xff0c;也包括云数据库&#xff0c;云数据库涉及产品RDS&#xff08;MySQL、PostgreSQL、MariaDB&#xff09;、Redis社区版、MongoDB、ClickHouse社区兼容版。阿里云百科aliyunbaike.com分享阿…