【poi导出excel模板——通过建造者模式+策略模式+函数式接口实现】

poi导出excel模板——通过建造者模式+策略模式+函数式接口实现

  • poi导出excel示例
  • 优化思路
  • 代码实现
  • 补充
    • 建造者模式
    • 策略模式

poi导出excel示例

首先我们现看一下poi如何导出excel,这里举个例子:目前想要导出一个Map<sex,List>信息,sex作为一个sheet页,Person信息包含姓名、年龄、籍贯等,在Person下还有一个List属性,里面包含名称、时长等,这里需要通过http的response导出文件

代码如下:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;public class ExcelExportExample {public static void exportToResponse(Map<String, List<Person>> data, HttpServletResponse response) {try {response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // 对于.xlsx格式// 或者使用 response.setContentType("application/vnd.ms-excel"); 对于.xls格式response.setHeader("Content-Disposition", "attachment; filename=output.xlsx"); // 文件名可以根据需要修改try (Workbook workbook = new XSSFWorkbook()) { // 或者使用 HSSFWorkbook for .xls 格式for (Map.Entry<String, List<Person>> entry : data.entrySet()) {String sheetName = entry.getKey();List<Person> personList = entry.getValue();Sheet sheet = workbook.createSheet(sheetName);// 创建表头行Row headerRow = sheet.createRow(0);headerRow.createCell(0).setCellValue("Name");headerRow.createCell(1).setCellValue("Age");headerRow.createCell(2).setCellValue("Hometown");headerRow.createCell(3).setCellValue("Hobby Name");headerRow.createCell(4).setCellValue("Hobby Duration");int rowNum = 1;for (Person person : personList) {Row row = sheet.createRow(rowNum++);// 填充 Person 基本信息Cell nameCell = row.createCell(0);nameCell.setCellValue(person.getName());Cell ageCell = row.createCell(1);ageCell.setCellValue(person.getAge());Cell hometownCell = row.createCell(2);hometownCell.setCellValue(person.getHometown());// 填充 Hobby 列表int hobbyColNum = 3;List<Hobby> hobbies = person.getHobbies();for (Hobby hobby : hobbies) {Cell hobbyNameCell = row.createCell(hobbyColNum++);hobbyNameCell.setCellValue(hobby.getName());Cell hobbyDurationCell = row.createCell(hobbyColNum++);hobbyDurationCell.setCellValue(hobby.getDuration());}}}try (OutputStream out = response.getOutputStream()) {workbook.write(out);} catch (IOException e) {e.printStackTrace();}}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {// 创建一个示例的 Map,每个 key 对应一个工作表(sheet)// 实际数据应根据业务需求和数据源进行设置// 示例中只包含了一个性别和一个 Person,你需要填充实际数据Map<String, List<Person>> data = createSampleData();// 获取 HttpServletResponse 对象并将数据导出到响应HttpServletResponse response = getHttpServletResponse(); // 你需要自行实现获取 HttpServletResponse 对象的方式exportToResponse(data, response);}

优化思路

代码中,可以看到创建工作簿、设置表头行、设置数据等操作都集中在一起,耦合性较高。如果后面再增加设置样式、设置不同类型单元格的样式,会全部集中到对workbook的操作上,而workbook又在开始时就创建了。
如果将workbook的创建于数据填充进行解耦。并且将创建工作簿、设置表头行、设置数据等操作作为一个公有方法抽取出来,可以供其他导出excel的业务进行使用。形成一个导出excel的公有类。
可以使用建造者模式+策略模式进行设计

代码实现

这里代码通过贴图方式介绍😂😂😂
在这里插入图片描述
首先介绍一下包,这里的样式形成一个策略接口,并且有一个默认实现,在strategy包下。然后是templete包,这里是存放具体业务的模板(比如有表头文字、属性映射等等),包含具体样式实现。
然后是一个建造器,用来构建workbook,这也是主要代码。所有代码放到了一个xssf包下,这里用到了excel2007的.xlsx格式的,其实也可以增加excel97的.xls格式。

建造器代码如下:

  1. 首先是workbook,因为在构造方法是需要传入这个workbook,并且是不可变对象,所以设置为final。
  2. 然后是将单元格样式设置为默认样式
  3. 下面就是对不同操作的方法抽取,分别有:创建sheet,设置样式,设置表头、设置数据等,当然,也可以扩展,比如设置列宽,行高这些内容。
  4. 在创建sheet中,使用到了setActiveSheet方法,这个让sheet创建后置为活动,以后就对这个shee进行操作,适合多sheet的表格文件。同时,在后面的操作中也能获取到当前操作的sheet。
    在这里插入图片描述
  5. 设置data这里,因为不同业务的数据格式、操作是不同的,因此没有通过参数方式直接传入数据,而是提供了函数式接口,让其在调用时能对当前这个sheet进行操作,从而设置数据。同时也可以设置样式。

样式策略接口代码如下:
这里只提供了列头样式和内容样式两个接口,其实可以进行扩展,比如指定sheet样式、行高、列宽等,可以将这些功能都抽取出来,用了修饰最终的workbook。
在这里插入图片描述
默认的样式策略实现如下:这里较为简单,就不做过多赘述。
在这里插入图片描述
具体使用
在这里插入图片描述
使用就比较简单了,只需要创建出建造器,我这里是有不同的sheet,传入了不同的值。然后填充列头,数据即可。
在这里插入图片描述
最后通过网络流导出,使用try-resource释放流。

补充

建造者模式

建造者模式是一种创建型设计模式,它用于构建复杂对象,将对象的构建步骤解耦并提供更好的控制和可读性。这种模式通常适用于需要创建具有多个可选参数或配置选项的对象,以确保对象构建过程灵活且易于理解。
举例就是springboot的启动的创建,典型的示例是 SpringApplicationBuilder 类,它用于创建 Spring Boot 应用程序的构建器

public class MySpringBootApp {public static void main(String[] args) {new SpringApplicationBuilder().sources(MySpringBootApp.class).bannerMode(Banner.Mode.CONSOLE).run(args);}
}

这样的创建型设计模式通常和行为型设计模式进行结合使用。

策略模式

策略模式是一种行为设计模式,它允许在运行时选择算法或行为的不同实现。这种模式定义了一组算法,将它们封装成独立的策略对象,并使它们可以互相替换。策略模式有助于使算法的选择独立于使用它们的客户端。
举个例子
Spring Boot 源码中广泛使用了策略模式,尤其在处理各种配置和扩展点时。一个典型的例子是 Spring Boot 的属性处理,其中使用了多种策略来解析配置属性。

Spring Boot 中的属性解析机制是通过 org.springframework.boot.context.properties.ConfigurationProperties 注解来实现的,它支持不同的属性源(如 application.properties、application.yml、环境变量等)和不同的解析策略。

@ConfigurationProperties("myapp")
public class MyProperties {private String property1;private int property2;// 省略 getter 和 setter// 配置属性解析策略@ConfigurationPropertiesBindingpublic static class MyPropertiesConverter implements Converter<String, MyProperties> {@Overridepublic MyProperties convert(String source) {// 解析配置属性并返回 MyProperties 对象// 这里可以根据不同的解析策略来处理属性的转换}}
}

在上述示例中,我们使用了 @ConfigurationProperties 注解来声明要处理的属性前缀(myapp),并定义了一个内部的属性解析策略类 MyPropertiesConverter,它实现了 Converter<String, MyProperties> 接口。

Spring Boot 的属性绑定机制将根据不同的属性源(例如 application.properties 文件或环境变量)自动选择相应的属性解析策略(例如 MyPropertiesConverter),并将属性值解析为 MyProperties 对象。

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

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

相关文章

idea2023如何查看被使用上下文关系

1.接口查看实现类&#xff0c;实现类查看接口 查看接口所有实现类 根据类里面的方法查看被覆盖的接口中的方法 2.查看方法、类被调用 3.查看类的继承关系

xcorr函数的用法和程序举例

xcorr函数的用法和程序举例 xcorr函数返回两个离散时间序列的互相关。互相关测量向量 x 和移位&#xff08;滞后&#xff09;副本向量y 的之间的相似性&#xff0c;形式为滞后的函数。如果 x 和 y 的长度不同&#xff0c;函数会在较短向量的末尾添加零&#xff0c;使其长度与另…

Flutter:安装依赖报错doesn‘t support null safety

项目中需要引用http依赖&#xff0c;在pubspec.yaml文件中添加如下信息&#xff1a; 当同步时&#xff0c;报错信息如下&#xff1a; [myflutter] flutter pub upgrade Resolving dependencies... The current Dart SDK version is 3.1.3. Because myflutter depends on http &…

Harmony 应用开发的知识储备

Harmony 应用开发的知识储备 前言正文一、DevEco Studio版本二、手机版本① 环境变量 三、API版本四、开发语言五、运行调试 前言 这里先说明一点&#xff0c;如果你对Android应用开发很熟悉&#xff0c;那么做Harmony应用开发也可以驾轻就熟&#xff0c;只不过在此之前你需要知…

TensorFlow学习笔记--(2)张量的常用运算函数

张量的取值函数 求张量的平均值: tf.reduce.mean(%张量名%)求张量的最小值:tf.reduce_min(%张量名%)求张量的最大值:tf.reduce_max(%张量名%)求张量的和:tf.reduce_sum(%张量名%)其次,对于上述所有操作 都可在函数后添加一个新的参数 axis%维度% axis0 代表第一维度 axis1 代表…

无人机航迹规划:五种最新智能优化算法(COA、SWO、KOA、GRO、LO)求解无人机路径规划MATLAB

一、五种算法&#xff08;LSO、SWO、KOA、GRO、LO&#xff09;简介 1、小龙虾优化算法COA 小龙虾优化算法&#xff08;Crayfsh optimization algorithm&#xff0c;COA&#xff09;由Jia Heming 等人于2023年提出&#xff0c;该算法模拟小龙虾的避暑、竞争和觅食行为&#xf…

浅谈工厂电能管理系统改造与产品选型

叶根胜 安科瑞电气股份有限公司 上海嘉定202001 摘要&#xff1a;随着经济的快速发展&#xff0c;能源紧张和环境恶化引起了全世界的密切关注。电能在所有能源中消耗量大&#xff0c;但不可或缺&#xff0c;因此对电能的统一管理尤为重要。只有准确可靠的计量电能、分级管理和…

物奇平台耳机宕机恢复功能实现

是否需要申请加入数字音频系统研究开发交流答疑群(课题组)&#xff1f;可加我微信hezkz17, 本群提供音频技术答疑服务&#xff0c;群赠送语音信号处理降噪算法&#xff0c;蓝牙音频&#xff0c;DSP音频项目核心开发资料, 物奇平台耳机宕机恢复功能实现 一 需求与场景 1 使…

QWidget 实现九宫格图案解锁

前言 最近需要实现一个九宫格图案解锁功能,查看网上的方案,基于QWidget的方案全网搜来搜去就一篇 Qt编写自定义控件:图案密码锁, 都是炒来炒去的同一篇,代码还比较复杂,运行后在PC端还是可以的,但是运行在arm机器上,就卡顿,或者容易断开手势连接线,各种不友好,于是自…

双11狂欢最后一天

大家好&#xff0c;本年度双11即将到来&#xff0c;为了答谢大家多年来的支持及更广泛的推广VBA的应用&#xff0c;“VBA语言専功”在此期间推出巨大优惠&#xff1a;此期间打包购买VBA技术资料实行半价优惠。 1&#xff1a;面向对象&#xff1a;学员及非学员 2&#xff1a;打…

另辟蹊径者 PoseiSwap:背靠潜力叙事,构建 DeFi 理想国

前不久&#xff0c;灰度在与 SEC 就关于 ETF 受理的诉讼案件中&#xff0c;以灰度胜诉告终。灰度的胜利&#xff0c;也被加密行业看做是加密 ETF 在北美地区阶段性的胜利&#xff0c; 该事件也带动了加密市场的新一轮复苏。 此前&#xff0c;Nason Smart Money 曾对加密市场在 …

时序预测 | MATLAB实现基于SVM-Adaboost支持向量机结合AdaBoost时间序列预测

时序预测 | MATLAB实现基于SVM-Adaboost支持向量机结合AdaBoost时间序列预测 目录 时序预测 | MATLAB实现基于SVM-Adaboost支持向量机结合AdaBoost时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.Matlab实现SVM-Adaboost时间序列预测&#xff08;风…

C/C++ 动态内存管理(内存是如何分布的?malloc/new,free/delete的用法是什么?区别是什么?)

目录 一、前言 二、C/C中的内存分布 &#x1f4a6;了解内存区域的划分 &#x1f4a6;内存存储区域的对比和注意点 &#x1f4a6;内存管理的常考面试题 三、C语言的动态管理方式 四、C的动态管理方式 &#x1f4a6;new / delete 操作内置类型&#xff08;int,char.....&…

【EI会议征稿】第八届先进能源科学与自动化国际研讨会(AESA 2024)

第八届先进能源科学与自动化国际研讨会&#xff08;AESA 2024) 2024 8th International Workshop on Advances in Energy Science and Automation 继AESA 2017-2023相继成功举办之后&#xff0c;来自国内外多所高校、科研院所及企业代表在先进能源科学与自动化的科研合作和交流…

Leetcode_3:无重复字符的最长子串

题目描述&#xff1a; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。 示例 2: 输入: s "bbbbb"…

小程序版本审核未通过,需在开发者后台「版本管理—提交审核——小程序订单中心path」设置订单中心页path,请设置后再提交代码审核

小程序版本审核未通过&#xff0c;需在开发者后台「版本管理—提交审核——小程序订单中心path」设置订单中心页path&#xff0c;请设置后再提交代码审核 因小程序尚未发布&#xff0c;订单中心不能正常打开查看&#xff0c;请先发布小程序后再提交订单中心PATH申请 初次提交…

强化IP地址管理措施:确保网络安全与高效性

IP地址管理是网络安全和性能管理的关键组成部分。有效的IP地址管理可以帮助企业确保网络的可用性、安全性和高效性。本文将介绍一些强化IP地址管理的关键措施&#xff0c;以帮助企业提高其网络的安全性和效率。 1. IP地址规划 良好的IP地址规划是强化IP地址管理的基础。它涉及…

具名挂载和匿名挂载

匿名卷挂载 &#xff1a; -v 的时候只指定容器内的路径 如下面这个&#xff1a;/etc/nginx 1.docker run -d -P --name nginx -v /etc/nginx nginx 2.查看所有卷 docker volume ls 这里发现&#xff0c;这就是匿名挂载&#xff0c;只指定容器内的路径&#xff0c;没有指定…

类图复习:类图简单介绍

入职新公司在看新项目的代码&#xff0c;所以借助类图梳理各个类之间的关系&#xff0c;奈何知识已经还给了老师&#xff0c;不得不重新学习下类图的相关知识&#xff0c;此处将相关内容记录下方便后续使用。 文章目录 类图语法类与类的关系画类图 类图语法 语法描述public-pr…

算术运算符、自增自减运算符、赋值运算符、关系运算符、逻辑运算符、三元运算符

1.算术运算符 public class OperatorDemo1 {public static void main(String[] args) {int a 10;int b 2;System.out.println(a b);System.out.println(a - b);System.out.println(a * b);System.out.println(a / b);System.out.println(5 / 2);System.out.println(5.0 / 2);…