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

easyPoi实现动表头Excel的导入和导出

easyPoi实现动表头Excel的导入和导出

Maven依赖

!-- EasyPoi 核心依赖 --><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>4.4.0</version></dependency><!-- EasyPoi Web支持 --><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-web</artifactId><version>4.4.0</version></dependency><!-- EasyPoi 注解支持 --><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-annotation</artifactId><version>4.4.0</version></dependency><!-- Apache POI 基础包 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><!-- 处理 Excel 2007+ (xlsx) 必须的包 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency><!-- 处理 XMLSchema/XSSF 时需要的 (推荐加上) --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>4.1.2</version></dependency><!-- 如果要导出图片、图表,推荐再加上 ooxml-schemas 全量包 --><dependency><groupId>org.apache.poi</groupId><artifactId>ooxml-schemas</artifactId><version>1.4</version></dependency>

实现类

/*** Created by ls on 2025/9/14.*/
@RestController
public class EasypoiController {/*** 导出 Excel (动态表头)* 访问: http://localhost:8080/exportDynamic*/@GetMapping("/exportDynamic")public void exportDynamic(HttpServletResponse response) throws Exception {// 1. 动态表头配置(实际项目可从前端传参)List<ExcelExportEntity> entityList = new ArrayList<>();entityList.add(new ExcelExportEntity("姓名", "name"));entityList.add(new ExcelExportEntity("年龄", "age"));entityList.add(new ExcelExportEntity("城市", "city"));entityList.add(new ExcelExportEntity("成绩", "score"));// 2. 模拟数据List<Map<String, Object>> dataList = new ArrayList<>();dataList.add(mapOf("name", "张三", "age", 18, "city", "北京", "score", 95));dataList.add(mapOf("name", "李四", "age", 20, "city", "上海", "score", 88));dataList.add(mapOf("name", "王五", "age", 22, "city", "广州", "score", 92));// 3. 生成 WorkbookExportParams params = new ExportParams("学生信息表", "Sheet1");Workbook workbook = ExcelExportUtil.exportExcel(params, entityList, dataList);// 4. 设置响应头并下载String fileName = URLEncoder.encode("动态表头示例.xlsx", "UTF-8");response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setHeader("Content-Disposition", "attachment;filename=" + fileName);workbook.write(response.getOutputStream());}// 小工具方法:快速构造 Mapprivate static Map<String, Object> mapOf(Object... kv) {Map<String, Object> m = new LinkedHashMap<>();for (int i = 0; i < kv.length; i += 2) {m.put(String.valueOf(kv[i]), kv[i + 1]);}return m;}/*** 动态导出 Excel* @param response HttpServletResponse*/@GetMapping("/export")public void exportExcel(HttpServletResponse response) throws Exception {// ======= 1. 动态表头定义(可从前端传 JSON,这里写死示例) =======List<ExcelExportEntity> entityList = new ArrayList<>();entityList.add(new ExcelExportEntity("姓名", "name"));entityList.add(new ExcelExportEntity("年龄", "age"));entityList.add(new ExcelExportEntity("城市", "city"));entityList.add(new ExcelExportEntity("成绩", "score"));// ======= 2. 模拟数据 =======List<Map<String, Object>> dataList = new ArrayList<>();dataList.add(mapOf("name", "张三", "age", 18, "city", "北京", "score", 95));dataList.add(mapOf("name", "李四", "age", 20, "city", "上海", "score", 88));// ======= 3. 生成 Excel =======ExportParams params = new ExportParams("学生信息表", "Sheet1");Workbook workbook = ExcelExportUtil.exportExcel(params, entityList, dataList);// ======= 4. 输出到浏览器 =======String fileName = URLEncoder.encode("动态导出.xlsx", "UTF-8");response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setHeader("Content-Disposition", "attachment;filename=" + fileName);workbook.write(response.getOutputStream());}/*** 动态导入 Excel* @param file 上传的 Excel 文件* @return 统一字段的数据*/@PostMapping("/import")public Map<String, Object> importExcel(@RequestParam("file") MultipartFile file) throws Exception {try (InputStream is = file.getInputStream();Workbook workbook = WorkbookFactory.create(is)) {Sheet sheet = workbook.getSheetAt(0);DataFormatter formatter = new DataFormatter();int headerStart = 1; // 从第二行开始,索引是 1(第一行索引是0)int headRows = 1; // 表头占一行int firstCol = 0;int lastCol = sheet.getRow(headerStart).getLastCellNum();// 组装表头List<String> headers = new ArrayList<>();Row headerRow = sheet.getRow(headerStart);for (int c = firstCol; c < lastCol; c++) {Cell cell = headerRow.getCell(c);String val = cell != null ? formatter.formatCellValue(cell).trim() : "COLUMN_" + c;headers.add(val);}// 遍历数据行List<Map<String, Object>> data = new ArrayList<>();int lastRow = sheet.getLastRowNum();for (int r = headerStart + headRows; r <= lastRow; r++) {Row row = sheet.getRow(r);if (row == null) continue;Map<String, Object> map = new LinkedHashMap<>();boolean allEmpty = true;for (int c = firstCol; c < lastCol; c++) {Cell cell = row.getCell(c);String val = cell != null ? formatter.formatCellValue(cell).trim() : "";if (!val.isEmpty()) allEmpty = false;map.put(headers.get(c - firstCol), val);}if (!allEmpty) data.add(map);}Map<String, Object> resp = new HashMap<>();resp.put("headers", headers);resp.put("data", data);return resp;}}}

文章转载自:

http://4BBqhQJL.qnzpg.cn
http://Qn0XlXBA.qnzpg.cn
http://lxHVWb7H.qnzpg.cn
http://lnEM200h.qnzpg.cn
http://qfWn9Lzz.qnzpg.cn
http://Sjmwl6Zv.qnzpg.cn
http://SkIYmdGa.qnzpg.cn
http://3O09S9Lt.qnzpg.cn
http://L0NZDsGy.qnzpg.cn
http://ChbO8i9T.qnzpg.cn
http://3q80GIuL.qnzpg.cn
http://hDWSBH1n.qnzpg.cn
http://lncsRMf4.qnzpg.cn
http://FddtURSv.qnzpg.cn
http://AvfXXkhV.qnzpg.cn
http://lai6mRbU.qnzpg.cn
http://dD5PX4Me.qnzpg.cn
http://tClri0Zs.qnzpg.cn
http://p0R7AWjq.qnzpg.cn
http://6BNJrEHn.qnzpg.cn
http://96M5Pw2X.qnzpg.cn
http://mPtpX8gk.qnzpg.cn
http://OqfJWnhK.qnzpg.cn
http://kKkmwI6A.qnzpg.cn
http://GwQJZcY9.qnzpg.cn
http://0kNPwL4G.qnzpg.cn
http://3kryVpSH.qnzpg.cn
http://lFu10rT4.qnzpg.cn
http://1dosCMvK.qnzpg.cn
http://wDJWMzNM.qnzpg.cn
http://www.dtcms.com/a/382852.html

相关文章:

  • 【Zephyr电源与功耗专题】13_PMU电源驱动介绍
  • Coze源码分析-资源库-创建知识库-后端源码-应用/领域/数据访问
  • React Server Components (RSC) 与 App Router 简介:Next.js 的未来范式
  • 状态机SMACH相关教程介绍与应用案例分析——机器人操作进阶系列之一
  • Grafana与Prometheus实战
  • godot+c#操作godot-sqlite并加解密
  • Scikit-learn 机器学习:构建、训练与评估预测模型
  • React学习教程,从入门到精通,React 组件核心语法知识点详解(类组件体系)(19)
  • Java分布式编程:RMI机制
  • 5-12 WPS JS宏 Range数组规范性测试
  • MySQL 的安装、启动、连接(Windows、macOS 和 Linux)
  • (附源码)基于Spring Boot的宿舍管理系统设计
  • Mac下Python3安装
  • C++数组与字符串:从基础到实战技巧
  • 第13课:分布式Agent系统
  • Docker 容器化部署核心实战——Nginx 服务配置与正反向代理原理解析
  • 【分享】中小学教材课本 PDF 资源获取指南
  • 如何用 Git Hook 和 CI 流水线为 FastAPI 项目保驾护航?
  • 安卓旋转屏幕后如何防止数据丢失-ViewModel入门
  • STM32_05_时钟树
  • 元宇宙与体育产业:沉浸式体验重构体育全链条生态
  • LeetCode 每日一题 966. 元音拼写检查器
  • C++密码锁 2023年CSP-S认证真题 CCF信息学奥赛C++ 中小学提高组 第二轮真题解析
  • Vue3 视频播放器完整指南 – @videojs-player/vue 从入门到精通
  • 零售企业数字化转型的道、法、术:基于开源AI大模型AI智能名片S2B2C商城小程序的战略重构
  • 【编号500】(道路分类)广东路网数据广东路网分类数据(2025年)
  • 【PHP7内核剖析】-1.3 FPM
  • 网络编程之UDP广播与粘包问题
  • h3笔记:polygon
  • Unity 性能优化 之 编辑器创建资源优化( 工作流 | 场景 | 预制体)