0. 这里假设 SSM 环境已经搭建完成

1. 需要三个依赖包

<!-- 导出为 Excel -->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.0.0</version>
</dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.0.0</version>
</dependency><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.10</version>
</dependency>

2. 核心工具类

目标是传入泛型数据列表 List dataList 实现将所有类型输出为 excel 表格,而不需要自己手动指定属性,所以对类的操作必不可少

这里利用反射达到了类的成员变量名
以及得到成员变量名和其值的映射关系(使用 Map,键是成员变量名 String ,值是成员变量值 Object)

ClassUtils.java

package com.iceclean.utils;import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @author : Ice'Clean* @date : 2021-08-05** 对类的操作*/
public class ClassUtils {/*** 通过类型返回对应的属性列表* @param target 目标类型* @return 属性列表*/public static List<String> getFields(Class<?> target) {// 获取所有成员变量名称List<String> fieldList = new ArrayList<>();Field[] declaredFields = target.getDeclaredFields();// 放入 List 集合中for(Field field : declaredFields) {fieldList.add(field.getName());}return  fieldList;}/*** 获取泛型所有的成员及其值的映射* @param data 泛型对象* @param <T> 泛型* @return 成员变量名和成员变量值的映射*/public static <T> Map<String, Object> getFieldOfValue(T data) throws IllegalAccessException {// 获取所有成员变量,并建立一个 Map(大小为成员变量的个数)来存放名字和值的对应关系Field[] declaredFields = data.getClass().getDeclaredFields();Map<String, Object> fieldMap = new HashMap<>(declaredFields.length);// 获取每个成员属性对应的值,并映射for (Field field : declaredFields) {// 允许访问私有变量的值field.setAccessible(true);// 获取成员变量的值,并放入 map 中fieldMap.put(field.getName(), field.get(data));}return fieldMap;}}

3. 核心代码

/*** 将列表数据导出为 Excel 表格* @param dataList 列表数据* @param out 输出源* @param <T> 数据的类型*/
public static <T> void exportExcel(List<T> dataList, ServletOutputStream out) throws IllegalAccessException, IOException {// 空集合直接返回if (dataList.isEmpty()) {return;}// 获取泛型 T 的所有成员变量List<String> fieldList = ClassUtils.getFields(dataList.get(0).getClass());// 建立一个 Excel 文件,并在文件中创建一个表单HSSFWorkbook workbook = new HSSFWorkbook();HSSFSheet sheet = workbook.createSheet();// 创建行(表头)HSSFRow row = sheet.createRow(0);// 创建单元格,并设置表头居中HSSFCellStyle hssfCellStyle = workbook.createCellStyle();hssfCellStyle.setAlignment(HorizontalAlignment.CENTER);// 循环设置列名HSSFCell hssfCell;for (int i = 0; i < fieldList.size(); i++) {hssfCell = row.createCell(i);hssfCell.setCellValue(fieldList.get(i));hssfCell.setCellStyle(hssfCellStyle);}// 为每一行添加数据Map<String, Object> dataMap;for (int i = 0; i < dataList.size(); i++) {// 添加新的一行row = sheet.createRow(i + 1);// 获取泛型对象 T 的成员变量和值的对应关系dataMap = ClassUtils.getFieldOfValue(dataList.get(i));// 将数据写入该行for (int j = 0; j < fieldList.size(); j++) {// 先通过 list 获取成员变量名,再通过 map 获取对应的值,转化为 String 之后放入表格中row.createCell(j).setCellValue("" + dataMap.get(fieldList.get(j)));}}// 将数据输出,刷出,关闭workbook.write(out);out.flush();;out.close();
}

同样是三步完成~


接下来是简单的使用演示
这里 Controller 层为了简化演示,使用了 Get 请求,制造数据也只起演示作用,可以自行替换

其中使用的 User 包含了 userId(Integer)userName(String)和 userPass(String)三个属性

=== Controller 层 ===@GetMapping("/excel")
@ResponseBody
public void exportExcel(HttpServletResponse response) throws IOException, IllegalAccessException {// 设置 ContentType 和返回头response.setContentType("application/binary;charset=UTF-8");response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode("导出"+new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) +".xls", "UTF-8"));//获得输出流ServletOutputStream out = response.getOutputStream();// 制造数据List<User> userList = new ArrayList<>();userList.add(new User(1, "iceclean", "ice123"));userList.add(new User(2, "len", "len123"));userList.add(new User(3, "rin", "rin123"));userList.add(new User(4, "rex", "rex123"));userList.add(new User(5, "alsie", "als123"));// 输出 excel 表格数据fileService.exportExcel(userList, out);
}=== Service 层 ===public <T> void exportExcel(List<T> dataList, ServletOutputStream out) throws IOException, IllegalAccessException {FileUtils.exportExcel(dataList, out);
}

Postman 上的演示:
什么值也不用传,可以看到返回的是乱码(其实是二进制流)

所以这里需要放到浏览器中去执行(可以用前端写个 post 方法,这里单纯使用 get 直接测试)

使用浏览器直接访问的效果:
将直接弹出个下载框

打开看里面的数据

任务圆满完成~~

▲ 与之相关的还有文件导出篇,可以看看这篇【纯干货】SSM 实现文件上传


2021-8-10 更新

对以上方法的不足之处作了改进,包括以下两点:

  • 当字段为空时,表格中直接显示为 null,可以改进为人为指定 null 的代替值
  • 表格中的列名直接为属性英文名,可以改进为人为指定其对应的中文名称

对空值的改进

简单的改进的话,只需要找到工具类 ClassUtils.java 中的 getFieldOfValue() 方法,对里边的值作判断即可
也可以将默认值作为字段提取出来成为形参,供调用者输入,这里不作演示了

// 获取每个成员属性对应的值,并映射
for (Field field : declaredFields) {// 允许访问私有变量的值field.setAccessible(true);// 获取属性值,并在其为空时赋予默认值String fieldData = field.get(data).toString();fieldData = fieldData == null ? "": fieldData;// 获取成员变量的值,并放入 map 中fieldMap.put(field.getName(), fieldData);
}

对列名的改进

① 首先添加自定义注解:
其中元注解 Target 表示注解使用在什么地方(这里设置为成员变量),Retention 设置注解在什么时候可以存在(这里设置为在运行期间可以被反射读取到)

/*** @author : Ice'Clean* @date : 2021-08-10** 为实体类的成员变量起名字*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldName {String value() default "名字";
}

② 然后在实体类中使用该注解
自定义属性名对应的中文名称

/*** @author : Ice'Clean* @date : 2021-08-05*/
public class User {@FieldName("用户 Id")private Integer userId;@FieldName("用户名")private String userName;@FieldName("用户密码")private String userPass;//... 省略
}

③ 在 ClassUtils.java 工具类中添加以下方法

/*** 通过类型返回对应的属性名称列表* 名称为该属性上的 FieldName(自定义注解) 的值* @param target 目标类型* @return 属性对应的中文名称列表*/
public static List<String> getFieldNames(Class<?> target) {// 获取所有成员变量名称List<String> fieldList = new ArrayList<>();Field[] declaredFields = target.getDeclaredFields();// 放入 List 集合中for(Field field : declaredFields) {// 获取该成员变量注解 FieldName 的值,即其对应的中文名称// 这里通过反射,取出了属性中的 value 值,即属性对象的中文名称fieldList.add(field.getAnnotation(FieldName.class).value());}return  fieldList;
}

④ 对核心代码进行改进
改动的地方很简单,增加一个中文名称列表(从上面方法中获得),将列名的填充值改成由该列表填充即可

/*** 将列表数据导出为 Excel 表格* @param dataList 列表数据* @param out 输出源* @param <T> 数据的类型*/
public static <T> void exportExcel(List<T> dataList, ServletOutputStream out) throws IllegalAccessException, IOException {// 空集合直接返回if (dataList.isEmpty()) {return;}// 获取泛型 T 的所有成员变量// 这里的第一种是获取原属性名,第二种是获取属性对应的注解 FieldName 的值,即对应的中文名称List<String> fieldList = ClassUtils.getFields(dataList.get(0).getClass());List<String> fieldNameList = ClassUtils.getFieldNames(dataList.get(0).getClass());// 建立一个 Excel 文件,并在文件中创建一个表单HSSFWorkbook workbook = new HSSFWorkbook();HSSFSheet sheet = workbook.createSheet();// 创建行(表头)HSSFRow row = sheet.createRow(0);// 创建单元格,并设置表头居中HSSFCellStyle hssfCellStyle = workbook.createCellStyle();hssfCellStyle.setAlignment(HorizontalAlignment.CENTER);// 循环设置列名(这里使用注解对应的中文名)HSSFCell hssfCell;for (int i = 0; i < fieldNameList.size(); i++) {hssfCell = row.createCell(i);hssfCell.setCellValue(fieldNameList.get(i));hssfCell.setCellStyle(hssfCellStyle);}// 为每一行添加数据Map<String, Object> dataMap;for (int i = 0; i < dataList.size(); i++) {// 添加新的一行row = sheet.createRow(i + 1);// 获取泛型对象 T 的成员变量和值的对应关系dataMap = ClassUtils.getFieldOfValue(dataList.get(i));// 将数据写入该行for (int j = 0; j < fieldList.size(); j++) {// 先通过 list 获取成员变量名,再通过 map 获取对应的值,转化为 String 之后放入表格中row.createCell(j).setCellValue("" + dataMap.get(fieldList.get(j)));}}// 将数据输出,刷出,关闭workbook.write(out);out.flush();;out.close();
}

⑤ 最终效果:


晨露夜集(IceClean)

【纯干货】SSM 实现将数据导出为 Excel 表格(利用反射实现类型通配)相关推荐

  1. 百度指数常见php框架,怎么导出数据到excel表格-如何将百度指数数据导出到Excel表格...

    如何将百度指数数据导出到Excel表格 第一步:打开CAD.CAD命令行输入"Li"."选择对象"选需要提取坐标的多段线.回车. 第二步:将CAD文本框中的数据 ...

  2. php怎么将表格导出到excel表格,php怎么将excel表格数据-php 怎么把数据导出到excel表格...

    如何使用php实现将数据从excel表导入到mysql中? /** * @param array $data //二维数组 不是对象 * @param string $filename //导件 */ ...

  3. php 链接excel表格数据,php 怎么把数据导出到excel表格?php 连接 excel表格数据库数据...

    php 怎么把数据导出到excel表格 php 把数据导出到excel表多种方法如使用 phpExcel 等,以下代码是直接通 header 生成 excel 文件的代码示例: header(&quo ...

  4. 查询php 输出表格,php输出excel表格数据-PHP如何将查询出来的数据导出成excel表格(最好做......

    PHP如何将查询出来的数据导出成excel表格(最好做... php 把数据导出excel表格有多种方法,使用 phpExcel 等,以下代码接通过 header 生成 excel 文件的代码示例: ...

  5. php 输入表格数据,怎样将导出数据输入Excel 表格-php 怎么把数据导出到excel表格...

    如何将word文档中的数据导入到excel表格中 方法如下: 1.首先,打开媒介工具"记事本",将word文件里需要导入的数据,复制粘贴到记事本当中,然后保存成为txt文件,本例中 ...

  6. 表格导出计算机,电脑怎么导出excel表格数据-如何将百度指数数据导出到Excel表格...

    系统没有导出功能,电脑表格里的数据有什么方法拿... 将网页表格数据导入到Excel中的方法: 第一步,将包括所需表格的网页打开,并按CTRL C把网址复制到剪贴板,以备下一步使用. 第二步,打开运行 ...

  7. 2021-08-01数据导出到Excel表格

    数据导出到Excel表格 https://www.cnblogs.com/zhangzhiyong-/p/13376527.html package com.jxmcloud.business.sho ...

  8. vb 读取oracle中的表格数据,如何将数据库信息读取导出excel表格中-VB 从SQL数据库中把数据导出到Excel表格中,怎么写?...

    VB 从SQL数据库中把数据导出到Excel表格中,怎么写? INSERT INTO OpenDataSource('Microsoft.Jet.OLEDB.4.0', 'Data Source=&q ...

  9. 阿里开源(EasyExcel):使用Java将数据导出为Excel表格、带样式----》java web下载 Excel文件

    目录 一.技术选型 二.实现过程 1.导入依赖 2.编写工具类 EasyExcelUtil 3.公用参数类 EasyExcelParams 4.表格样式实体类 MyWriteHandler 5.数据实 ...

最新文章

  1. 提升Web应用程序性能的最佳实践
  2. 使用HTML5的自定义数据属性的jQuery选择器
  3. 派生类的赋值运算符重载【C++继承】
  4. co11n——生产订单确认的BAPI
  5. 【转】x.509证书在WCF中的应用(CS篇)
  6. Java接口–历年来Java 9之旅–默认和私有方法
  7. 【转】如何在eclipse下配置Heritrix
  8. 阿里云Linux服务器配置Java环境
  9. 3种云桌面(VDI、IDV、VOI)技术解决方案简介
  10. 网易教程python_麻瓜编程Python Web 开发工程师微专业基础教程 - 网易云课堂
  11. Linux下如何解压.zip和.rar文件
  12. 每天一道算法题系列十七之电话号码的字母组合
  13. SDM、ESR、LBF、AAM
  14. 树莓派linux led字符设备驱动(信号量)
  15. 单位dbm db的关系与区别
  16. 【nowcoder 219641】天使果冻
  17. JAVAEE 实训日志 一
  18. Reaction Paper
  19. OpenCV实践之路——使用imread()函数读取图片的六种正确姿势
  20. 解决笔记本电脑win10系统指纹间歇性无法识别(失灵)的问题

热门文章

  1. MOOC 北大C语言-图像模糊处理
  2. Linux系统 06 python环境配置04 之 python操作redis
  3. html-css文字特效,7款震撼人心的HTML5CSS3文字特效
  4. 单片机自动售货机c语言,基于单片机的自动售货机
  5. DS||dfs and bfs
  6. 智能传感器的应用领域
  7. 360极速浏览器网页保护色
  8. 在win7系统中安装 Outlook Express
  9. 为什么merge的时候要用squash
  10. 使用异步爬虫爬取网络小说