当前位置: 首页 > news >正文

EasyPoi系列之框架集成及基础使用

EasyPoi系列之框架集成及基础使用

  • 1 EasyPoi
    • 1.1 gitee仓库地址
  • 2 EasyPoi集成至SpringBoot
    • 2.1 maven引入jar包
  • 3 EasyPoi Excel导出
    • 3.1 基于实体对象导出
      • 3.1.1 @Excel 注解
      • 3.1.2 编写实体
      • 3.1.3 编写导出方法
      • 3.1.4 导出效果
    • 3.2 基于模板导出
      • 3.2.1 编写模板文件
      • 3.2.2 编写导出方法
      • 3.2.3 导出效果
  • 4 EasyPoi 数据导入
    • 4.1 导入数据准备
    • 4.2 编写接口
    • 4.3 导入测试
      • 4.3.1 编写apiFox
      • 4.3.2 导入结果
      • 4.3.3 修改 "核定金额" 为“核定金额1”
  • 5 EasyPoi 模板填充
    • 5.1 模板表达式
    • 5.2 Excel模板填充导出
    • 5.3 Word模板填充导出
      • 5.3.1 模板准备
      • 5.3.2 编写导出代码
      • 5.3.3 导出效果
  • 6 总结

1 EasyPoi

官方介绍为:EasyPoi Excel和 Word简易工具类
easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 语言(熟悉的表达式语法),完成以前复杂的写法。

1.1 gitee仓库地址

https://gitee.com/wupaas/easypoi

2 EasyPoi集成至SpringBoot

2.1 maven引入jar包

<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>4.4.0</version>
</dependency>

3 EasyPoi Excel导出

3.1 基于实体对象导出

3.1.1 @Excel 注解

代码位于:cn.afterturn.easypoi.excel.annotation.Excel,用于通过注解标识实体字段,核心属性如下:

  • name:用于表示Excel表头
  • width:导出时在excel中每个列的宽 单位为字符,一个汉字=2个字符
  • suffix:文字后缀,如% 90 变成90%
  • isWrap:是否换行 即支持\n
  • type:导出类型 1 是文本 2 是图片,3 是函数,10 是数字, 11 特殊符号 默认是文本
  • enumExportField:枚举导出使用的字段

3.1.2 编写实体

import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;
/*** 导出实体*/
@Data
public class ExportEntity {@Excel(name = "序号",width = 20)private Integer index;@Excel(name = "资金性质",width = 50)private String accountType;@Excel(name = "项目名称",width = 50)private String projectName;@Excel(name = "申请金额",width = 50)private String amountApplied;@Excel(name = "核定金额",width = 50)private String approvedAmount;
}

3.1.3 编写导出方法

/*** 构建到处数据(模拟数据库查询)* @param num* @return*/
private List<ExportEntity> buildExportData(int num){List<ExportEntity> exportData = new ArrayList<>();ExportEntity exportEntity = null;for (int i = 0; i < num; i++) {exportEntity = new ExportEntity();exportEntity.setIndex(i+1);exportEntity.setAccountType("资金性质"+i);exportEntity.setProjectName("项目名称"+i);exportEntity.setAmountApplied("申请金额"+i);exportEntity.setApprovedAmount("核定金额"+i);exportData.add(exportEntity);}return exportData;
}/**
* 通过实体导出Excel
* @param response
*/
@RequestMapping("/excel/exportByEntity")
public void exportByEntity(HttpServletResponse response) throws Exception {ExportParams exportParams = new ExportParams();List<ExportEntity> datas = this.buildExportData(10);Workbook workbook = null;try{response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("测试exportByEntity", "utf-8") + ".xlsx");workbook = ExcelExportUtil.exportExcel(exportParams, ExportEntity.class, datas);workbook.write(response.getOutputStream());}finally {IoUtil.close(workbook);}
}

3.1.4 导出效果

浏览器访问 http://ip:port/excel/exportByEntity(根据实际情况进行替换),导出文件效果如下:
在这里插入图片描述

3.2 基于模板导出

3.2.1 编写模板文件

具体模板语法在后续会进行讲解
在这里插入图片描述

3.2.2 编写导出方法

/*** 构建到处数据(模拟数据库查询)* @param num* @return*/
private List<ExportEntity> buildExportData(int num){List<ExportEntity> exportData = new ArrayList<>();ExportEntity exportEntity = null;for (int i = 0; i < num; i++) {exportEntity = new ExportEntity();exportEntity.setIndex(i+1);exportEntity.setAccountType("资金性质"+i);exportEntity.setProjectName("项目名称"+i);exportEntity.setAmountApplied("申请金额"+i);exportEntity.setApprovedAmount("核定金额"+i);exportData.add(exportEntity);}return exportData;
}
/*** 通过模板导出* @param response*/
@RequestMapping("/excel/exportTemplate")
public void exportByTemplate(HttpServletResponse response) throws Exception{//exportTemplate.xlsx 放在resources目录下TemplateExportParams templateExportParams = new TemplateExportParams("templates/exportTemplate.xlsx");//定义map对象Map<String,Object> data = new HashMap<>();List<ExportEntity> datas = this.buildExportData(10);//将导出数据put至map中,注意此处的datas与模板$fe: 后的变量名称一致data.put("datas",datas);Workbook workbook = null;try{response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("测试exportTemplate", "utf-8") + ".xlsx");workbook = ExcelExportUtil.exportExcel(templateExportParams, data);workbook.write(response.getOutputStream());}finally {IoUtil.close(workbook);}
}

3.2.3 导出效果

浏览器访问 http://ip:port/excel/exportByEntity(根据实际情况进行替换),导出文件效果如下:
在这里插入图片描述
注意:通过模板导出,可以用于针对复杂表头,使用@Excel注解无法或不好实现场景。

4 EasyPoi 数据导入

4.1 导入数据准备

以3.1中导出的Excel为例,如下图:
在这里插入图片描述

4.2 编写接口

ExportEntity为3.1中导出文件时,定义的实体类

/*** excel导入* @param response*/
@PostMapping("/excel/importData")
@ResponseBody
public List<ExportEntity> importData(HttpServletResponse response, MultipartFile file) throws Exception{ImportParams importParams = new ImportParams();List<ExportEntity> datas = ExcelImportUtil.importExcel(file.getInputStream(), ExportEntity.class, importParams);return datas;
}

4.3 导入测试

4.3.1 编写apiFox

在ApiFox中新建请求如下图,选择对应的导入文件,点击发送
在这里插入图片描述

4.3.2 导入结果

如下图,通过图中可看出,数据已从Excel中读入到实体集合中
在这里插入图片描述

4.3.3 修改 “核定金额” 为“核定金额1”

将“核定金额” 修改为 “核定金额1”,如下图:
在这里插入图片描述

再次进行导入,可以看到,由于字段不匹配,未能成功导入:
在这里插入图片描述
注意:通过Excel进行导入时候,1、需要保证导入的实体注解上的内容要与Excel表头文本一致(前后空格会自动进行处理),2、如果存在多列相同的表头,会以最后一列为匹配数据进行导入。

5 EasyPoi 模板填充

5.1 模板表达式

  • 空格分割
  • 三目运算 {{test ? obj:obj2}}
  • n: 表示 这个cell是数值类型 {{n:}}
  • le: 代表长度{{le:()}} 在if/else 运用{{le:() > 8 ? obj1 : obj2}}
  • fd: 格式化时间 {{fd:(obj;yyyy-MM-dd)}}
  • fn: 格式化数字 {{fn:(obj;###.00)}}
  • fe: 遍历数据,创建row
  • !fe: 遍历数据不创建row
  • $fe: 下移插入,把当前行,下面的行全部下移.size()行,然后插入
  • !if: 删除当前列 {{!if:(test)}}
  • 单引号表示常量值 ‘’ 比如’1’ 那么输出的就是 1
  • &NULL& 控制
  • ]] 换行符

5.2 Excel模板填充导出

excel模板填充,可以参考3.2 基于模板导出

5.3 Word模板填充导出

5.3.1 模板准备

编写 纳税信息.docx,放置在resources/templates目录下,内容如下:
在这里插入图片描述

5.3.2 编写导出代码

/*** word 测试*/
@Controller
@RequestMapping("/word")
public class WordTestController {/*** 通过模板填充word文档* @param response*/@RequestMapping("/exportByTemplate")public void exportByTemplate(HttpServletResponse response){try {//模拟从数据库读取数据List<Map<String,String>> taxlist = new ArrayList<>();Map<String,String> tax1= new HashMap<>();tax1.put("type","税种1");tax1.put("presum","1");tax1.put("thissum","2");tax1.put("curmonth","1");tax1.put("now","2025-02-18");taxlist.add(tax1);Map<String,String> tax2= new HashMap<>();tax2.put("type","税种2");tax2.put("presum","3");tax2.put("thissum","4");tax2.put("curmonth","2");tax2.put("now","2025-02-19");taxlist.add(tax2);Map<String,Object> data = new HashMap<>();data.put("taxlist",taxlist);Map<String,String> total= new HashMap<>();total.put("totalpreyear","4");total.put("totalthisyear","5");data.put("total",total);data.put("totalpreyear","测试3");data.put("totalthisyear","测试4");response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("测试exportByTemplate", "utf-8") + ".docx");//传入模板地址与模板变量进行填充try(XWPFDocument head  = WordExportUtil.exportWord07("templates/纳税信息.docx",data )){head.write(response.getOutputStream());}}catch (Exception e) {e.printStackTrace();}}
}

5.3.3 导出效果

浏览器访问 http://ip:port/word/exportByTemplate(根据实际情况进行替换),导出文件效果如下:
在这里插入图片描述
注意:通过模板导出,可以用于订单填充、合同数据填充等应用场景,能够较好的保留原格式;结合笔者文章 “kkFileView二开之word转pdf接口”,可以快速实现合同文件生成的需求

6 总结

工欲善其事必先利其器。在日常工作中,需要多了解相关的三方组件,以便于在将来遇到类似的需求的时候,能够尽快的提出对应的解决方案,以展现自己的专业能力。

相关文章:

EasyPoi系列之框架集成及基础使用

EasyPoi系列之框架集成及基础使用 1 EasyPoi1.1 gitee仓库地址 2 EasyPoi集成至SpringBoot2.1 maven引入jar包 3 EasyPoi Excel导出3.1 基于实体对象导出3.1.1 Excel 注解3.1.2 编写实体3.1.3 编写导出方法3.1.4 导出效果 3.2 基于模板导出3.2.1 编写模板文件3.2.2 编写导出方法…...

Web后端 Tomcat服务器

一 Tomcat Web 服务器 介绍&#xff1a; Tomcat是一个开源的Java Servlet容器和Web服务器&#xff0c;由Apache软件基金会开发。它实现了Java Servlet和JavaServer Pages (JSP) 技术&#xff0c;用于运行Java Web应用程序。Tomcat轻量、易于配置&#xff0c;常作为开发和部署…...

【RK3588嵌入式图形编程】-SDL2-构建模块化UI

构建模块化UI 文章目录 构建模块化UI1、概述2、创建UI管理器3、嵌套组件4、继承5、多态子组件6、总结在本文中,将介绍如何使用C++和SDL创建一个灵活且可扩展的UI系统,重点关注组件层次结构和多态性。 1、概述 在前面的文章中,我们介绍了应用程序循环和事件循环,这为我们的…...

面向机器学习的Java库与平台简介、适用场景、官方网站、社区网址

Java机器学习的库与平台 最近听到有的人说要做机器学习就一定要学Python&#xff0c;我想他们掌握的知道还不够系统全面。本文作者给大家介绍几种常用Java实现的机器学习库&#xff0c;快快收藏加关注吧&#xff5e; Java机器学习库表格 Java机器学习库整理库/平台概念适合场…...

基于YOLO11深度学习的心脏超声图像间隔壁检测分割与分析系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分割、人工智能

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...

ubuntu24基于虚拟机无法从主机拖拽文件夹

以下是解决问题的精简步骤&#xff1a; 安装 open-vm-tools-desktop&#xff1a; bash复制 sudo apt-get install open-vm-tools-desktop 重启虚拟机后&#xff0c;文字复制粘贴功能可正常工作。 禁用 Wayland&#xff1a; 编辑 /etc/gdm3/custom.conf 文件&#xff1a; bash复…...

常用Webpack Loader汇总介绍

引言 在前端项目开发中&#xff0c;Webpack 作为强大的模块打包工具&#xff0c;能够将各种资源进行打包处理。而其中的 Loader 则是 Webpack 处理不同类型文件的关键&#xff0c;它允许 Webpack 不仅仅局限于处理 JavaScript 文件&#xff0c;还能处理 CSS、图片、字体等多种…...

剑指 Offer II 023. 两个链表的第一个重合节点

comments: true edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20023.%20%E4%B8%A4%E4%B8%AA%E9%93%BE%E8%A1%A8%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E9%87%8D%E5%90%88%E8%8A%82%E7%82%B9/README.md 剑指 Offer II 023. 两…...

个人搭建CDN加速服务 特网科技

在互联网快速发展的今天&#xff0c;网站的加载速度对用户体验有着至关重要的影响&#xff0c;传统的网页加载方式依赖于服务器的性能和网络环境&#xff0c;这使得某些网站的页面加载时间过长&#xff0c;用户体验不佳&#xff0c;为了解决这个问题&#xff0c;许多企业开始采…...

用deepseek学大模型08-卷积神经网络(CNN)

yuanbao.tencent.com 从入门到精通卷积神经网络(CNN),着重介绍的目标函数&#xff0c;损失函数&#xff0c;梯度下降 标量和矩阵形式的数学推导&#xff0c;pytorch真实能跑的代码案例以及模型,数据&#xff0c;预测结果的可视化展示&#xff0c; 模型应用场景和优缺点&#xf…...

蓝桥杯单片机基础部分——6、555定时器

前言 NE555是一个纯硬件的设计&#xff0c;旦硬件电路确定了&#xff0c;其功能也确定了&#xff0c;没有可编程的部分&#xff0c;也没什么好去理解的地方&#xff0c;如果理解不了就直接背代码&#xff0c;这里也不是很常考&#xff0c;大家了解一下就可以了&#xff0c;知道…...

Python学习心得函数

一、函数的定义及调用 1.函数的定义&#xff1a; 函数的定义&#xff1a;函数是将一段能实现某种特定功能的代码&#xff0c;使用函数名进行封装&#xff0c;并通过函数名称进行调用。从而达到一次编写&#xff0c;多次调用的目的。 2.函数类型分为两类&#xff1a; &#…...

神经网络实验——MLP

目录 1 目的 2 方法 3 源代码 4 结果 1 目的 ①熟悉 Python 的输入输出流; ②学会使用 matplotlib进行图像可视化; ③掌握神经网络的基本原理&#xff0c;学会使用 sklearn 库中的 MLPClassifier 函数构建基础的多层感知机神经网络分类器; ④学会使用网格查找进行超参数优…...

配置Api自动生成

我的飞书:https://rvg7rs2jk1g.feishu.cn/docx/TVlJdMgYLoDJrsxAwMgcCE14nxt 使用Springfox Swagger生成API&#xff0c;并导入Postman&#xff0c;完成API单元测试 Swagger: 是一套API定义的规范&#xff0c;按照这套规范的要求去定义接口及接口相关信息&#xff0c;再通过可…...

dify-AI 私有部署可修改前端页面

dify文档 官方文档&#xff1a;欢迎使用 Dify | Dify 源码&#xff1a;https://github.com/langgenius/dify.git 安装docker 官网&#xff1a;https://www.docker.com/ 部署服务到docker cd dify cd docker cp .env.example .env docker compose up -d查看效果 http://localh…...

使用 @Results 注解来手动指定字段映射

在 MyBatis 中&#xff0c;Results 注解用于手动指定查询结果的字段映射&#xff0c;尤其当数据库列名与 Java 对象的字段名不一致时。你可以通过 Results 和 Result 注解来精确控制每一列与类属性之间的映射关系。 示例&#xff1a;使用 Results 注解来手动指定字段映射 假设你…...

数据治理中 大数据处理一般都遵循哪些原则

在数据治理中&#xff0c;大数据处理通常遵循以下原则&#xff1a; 最小化原则&#xff1a;企业应只收集实现特定目的所需的数据&#xff0c;避免数据冗余和安全风险。 合法性原则&#xff1a;企业必须遵守相关法律法规&#xff0c;确保数据处理符合法律要求&#xff0c;降低法…...

从0到1:STM32温控系统开发踩坑指南

1. 设计目标 核心功能&#xff1a;实现0-100℃范围内的温度闭环控制 性能指标&#xff1a; 测量精度&#xff1a;0.5℃&#xff08;使用DS18B20传感器&#xff09; 控制响应时间&#xff1a;<5秒 显示分辨率&#xff1a;0.1℃ 扩展功能&#xff1a; LCD实时显示当前温度…...

修改时无条件,可以自定义id条件(通过查询)

在这段代码中&#xff0c;$(row).attr(data-rarity, data.rarity); 的作用是给表格的每一行 (row) 添加一个 data-rarity 的自定义属性&#xff0c;属性的值是该行数据中的 rarity 字段。 解释&#xff1a; 1.row 是当前行的 DOM 元素。 2.data.rarity 是从 data 对象中获取的…...

工业制造能耗管理新突破,漫途MTIC-ECM平台助力企业绿色转型!

在工业制造领域&#xff0c;能源消耗一直是企业运营成本的重要组成部分。随着“双碳”目标的推进&#xff0c;如何实现高效能耗管理&#xff0c;成为制造企业亟待解决的问题。漫途MTIC-ECM能源能耗在线监测平台&#xff0c;结合其自研的硬件产品&#xff0c;为工业制造企业提供…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

【C++】纯虚函数类外可以写实现吗?

1. 答案 先说答案&#xff0c;可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...

es6+和css3新增的特性有哪些

一&#xff1a;ECMAScript 新特性&#xff08;ES6&#xff09; ES6 (2015) - 革命性更新 1&#xff0c;记住的方法&#xff0c;从一个方法里面用到了哪些技术 1&#xff0c;let /const块级作用域声明2&#xff0c;**默认参数**&#xff1a;函数参数可以设置默认值。3&#x…...

leetcode73-矩阵置零

leetcode 73 思路 记录 0 元素的位置&#xff1a;遍历整个矩阵&#xff0c;找出所有值为 0 的元素&#xff0c;并将它们的坐标记录在数组zeroPosition中置零操作&#xff1a;遍历记录的所有 0 元素位置&#xff0c;将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...

从零手写Java版本的LSM Tree (一):LSM Tree 概述

&#x1f525; 推荐一个高质量的Java LSM Tree开源项目&#xff01; https://github.com/brianxiadong/java-lsm-tree java-lsm-tree 是一个从零实现的Log-Structured Merge Tree&#xff0c;专为高并发写入场景设计。 核心亮点&#xff1a; ⚡ 极致性能&#xff1a;写入速度超…...

更新 Docker 容器中的某一个文件

&#x1f504; 如何更新 Docker 容器中的某一个文件 以下是几种在 Docker 中更新单个文件的常用方法&#xff0c;适用于不同场景。 ✅ 方法一&#xff1a;使用 docker cp 拷贝文件到容器中&#xff08;最简单&#xff09; &#x1f9f0; 命令格式&#xff1a; docker cp <…...

day51 python CBAM注意力

目录 一、CBAM 模块简介 二、CBAM 模块的实现 &#xff08;一&#xff09;通道注意力模块 &#xff08;二&#xff09;空间注意力模块 &#xff08;三&#xff09;CBAM 模块的组合 三、CBAM 模块的特性 四、CBAM 模块在 CNN 中的应用 一、CBAM 模块简介 在之前的探索中…...