1.    依赖

我的项目是基于Spring Boot的,这里只贴出POI框架需要依赖的两个包,其他的都无所谓,只要能提供Controller让浏览器访问即可。在pom.xml配置文件中增加如下两个包:

       <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>

2. 代码实现

package com.eg.wiener.controller;

import com.eg.wiener.dto.User;
import com.eg.wiener.utils.ExcelUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream; /**
* @author Wiener
* @date 2020/9/5
*/
@Slf4j
@RestController
@RequestMapping("/excel")
public class ExcelExportController { private static HSSFWorkbook workbook = null;
// 代表一行记录
private static HSSFCell cell = null;
private static HSSFRow row = null; @RequestMapping(value = "/exportExcel")
public Object exportExcel(HttpServletRequest request, HttpServletResponse response) throws Exception {
String fileSuffix = ".xls";
String fileName = "导出数据至Excel示例"+ "_" + (int) (Math.random() * 9000 + 1000) + ".xls"; //【1】创建excel
workbook = new HSSFWorkbook();
// 设置表头的类型
HSSFCellStyle style = setCellStyle(workbook); // 创建一个sheet
HSSFSheet sheet = workbook.createSheet("sheet1"); try {
List<User> dataList = getUsers(); if (CollectionUtils.isNotEmpty(dataList)) {
//【2】 设置表头:对Excel每列命名
String[] tableHeader = Stream.of("编号", "姓名", "年龄").toArray(String[]::new);
// 设置Excel表头
row = ExcelUtils.getExcelRow(workbook, sheet, tableHeader);
//通过反射,获取POJO对象。由于同一个dataList中,POJO相同,故定义在for循环外部,提高遍历性能
Class cl = dataList.get(0).getClass();
//获取类的所有字段
Field[] fields = cl.getDeclaredFields();
//写入每一行的记录
for (int i = 0; i < dataList.size(); i++) {
//创建新的一行,递增
row = sheet.createRow(i + 1);
// 设置行高
row.setHeight((short) 400);
for (int j = 0; j < fields.length; j++) {
//设置字段可见,否则会报错,禁止访问
fields[j].setAccessible(true);
//创建单元格
cell = row.createCell(j);
cell.setCellValue(Objects.toString(fields[j].get(dataList.get(i)), ""));
cell.setCellStyle(style);
}
}
} else {
// 没有查到数据提示行
row = ExcelUtils.getNotResultInfoRow(workbook, sheet, "记录为空");
}
} catch (Exception e) {
log.error("导出数据失败:", e);
// 写入Excel失败原因
row = ExcelUtils.getNotResultInfoRow(workbook, sheet, "导出数据失败");
fileName = "导出数据失败";
}
fileName = fileName + "_" + (int) (Math.random() * 9000 + 1000) + fileSuffix; //下载文件
ExcelUtils.outputExcelStream(request, response, workbook, fileName); return "导出成功";
} private List<User> getUsers() {
List<User> list = new ArrayList<>();
User aUser = new User();
aUser.setAge(18);
aUser.setId(1);
aUser.setName("Tony");
list.add(aUser); aUser = new User();
aUser.setAge(21);
aUser.setId(2);
aUser.setName("Tom");
list.add(aUser);
aUser = new User();
aUser.setAge(20);
aUser.setId(3);
aUser.setName("店小二");
list.add(aUser);
return list;
} private HSSFCellStyle setCellStyle(HSSFWorkbook myWorkbook) {
HSSFCellStyle style = myWorkbook.createCellStyle();
//设置自动换行
style.setWrapText(true);
style.setAlignment(HorizontalAlignment.CENTER);
//设置边框样式
style.setBorderTop(BorderStyle.THIN);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
//设置边框颜色
style.setTopBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
style.setBottomBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
style.setLeftBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
style.setRightBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex()); HSSFDataFormat format = workbook.createDataFormat();
// 设置文本格式
style.setDataFormat(format.getFormat("@"));
// 设置字体
HSSFFont font = workbook.createFont();
font.setColor(Font.COLOR_RED);
font.setFontName("宋体");
font.setFontHeightInPoints((short) 12);// 12号字体
style.setFont(font);
return style;
}
}

通过反射获取POJO对象,故传入不同类型的POJO对象的dataList就可以了。下面是依赖的一个工具类:

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder; /**
* 导出Excel工具类
*
* @author Wiener
* @date 2020/9/5
*/
@Slf4j
public class ExcelUtils { /**
* 设置Excel表头
*
* @param workbook
* @param sheet
* @param tableHeader
* @return
*/
public static HSSFRow getExcelRow(HSSFWorkbook workbook, HSSFSheet sheet, String[] tableHeader) {
short cellNumber = (short) tableHeader.length;
// Excel的第一行表头
HSSFRow row = sheet.createRow(0);
// 设置行高
row.setHeight((short) 560);
// Excel的列
HSSFCell cell = null;
HSSFFont font = workbook.createFont();
// 粗体显示
font.setBold(Boolean.TRUE);
font.setFontHeightInPoints((short) 15);
// 设置单元格字体的颜色
font.setColor(HSSFFont.COLOR_NORMAL);
// 样式
HSSFCellStyle style = workbook.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER);
//设置边框样式
style.setBorderTop(BorderStyle.DOTTED);
style.setBorderBottom(BorderStyle.DOTTED);
style.setBorderLeft(BorderStyle.DOTTED);
style.setBorderRight(BorderStyle.DOTTED);
//设置边框颜色
style.setTopBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
style.setBottomBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
style.setLeftBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
style.setRightBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex()); for (int k = 0; k < cellNumber; k++) {
int i = 0;
i += k;
short b = 6000;
cell = row.createCell(i); // 创建第0行第k列
cell.setCellValue(tableHeader[k]); // 设置第0行第k列的值
sheet.setColumnWidth(i, b); // 设置列的宽度
style.setFont(font); // 设置字体风格
cell.setCellStyle(style);
}
return row;
} /**
* 设置Excel未获取数据提示行
*
* @param workbook
* @param sheet
* @return
*/
public static HSSFRow getNotResultInfoRow(HSSFWorkbook workbook, HSSFSheet sheet, String message) {
// Excel的第一行表头
HSSFRow row = sheet.createRow(0);
// Excel的列
HSSFCell cell = null;
// 设置表头的类型
HSSFCellStyle style = workbook.createCellStyle();
//设置自动换行
style.setWrapText(true);
style.setAlignment(HorizontalAlignment.CENTER); // 没有查到数据
row = sheet.createRow((short) (0)); // 创建第j+1行
row.setHeight((short) 1000); // 设置行高
sheet.setColumnWidth(0, 10000);
cell = row.createCell(0); // 创建第i+1行第1列
cell.setCellValue(message);//
cell.setCellStyle(style); // 设置风格 return row;
} /**
* 下载EXCEL,对不同浏览器做中文名称兼容<br/>
* 如果不对文件名进行编码处理,那么有些浏览器无法识别下载文件
*
* @param request
* @param response
* @param workbook
* @param fileName
*/
public static void outputExcelStream(HttpServletRequest request, HttpServletResponse response, HSSFWorkbook workbook, String fileName) {
OutputStream out = null;
try {
String excelFileName = fileName + "_" + (int) (Math.random() * 9000 + 1000) + ".xls";
if (isMsBrowser(request)) {
// ie,edge 浏览器
excelFileName = URLEncoder.encode(excelFileName, "UTF-8");
} else {
//其他的浏览器
excelFileName = new String(excelFileName.getBytes("UTF-8"), "iso-8859-1");
}
//输出流对象
out = response.getOutputStream();
// 设置文件头编码方式和文件名
response.setHeader("Content-Disposition", "attachment;filename=" + excelFileName);
// 设置类型
response.setContentType("application/msexcel;charset=UTF-8");
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
workbook.write(out);
out.flush();
workbook.write(out);
} catch (IOException e) {
log.error("下载EXCEL失败,", e);
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
log.error("下载EXCEL关闭文件流失败,", e);
}
}
} //判断是否是IE浏览器
private static boolean isMsBrowser(HttpServletRequest request) {
String userAgent = request.getHeader("User-Agent");
if (StringUtils.isBlank(userAgent)) {
return false;
}
String[] IEBrowserSignals = {"msie", "trident", "edge"};
for (String signal : IEBrowserSignals) {
if (userAgent.toLowerCase().contains(signal)) {
return true;
}
}
return false;
} }

在使用的时候,仅仅需要传入不同的表头集合、实体类集合,就能实现需求,这就是封装的魅力所在。

Spring Boot项目基于POI框架导出Excel表格的更多相关文章

  1. Spring Boot下的一种导出Excel文件的代码框架

    1.前言 ​ 在Spring Boot项目中,将数据导出成Excel格式文件是常见的功能.与Excel文件导入类似,此处也用代码框架式的方式实现Excel文件导出,使得代码具有可重用性,并保持导出数据 ...

  2. Vue项目中将table组件导出Excel表格以及打印页面内容

    体验更优排版请移步原文:http://blog.kwin.wang/programming/vue-table-export-excel-and-print.html 页面中显示的table表格,经常 ...

  3. java操作Excel的poi的导出Excel表格

    页面布局 点击导出用户:触发函数,直接访问后台 后台方法如下: public String export()throws Exception{ Connection con=null; try { c ...

  4. 启动Spring boot项目报错:java.lang.IllegalArgumentException: LoggerFactory is not a Logback

    java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on t ...

  5. js导出excel表格中较长数字串会变成科学计数法问题

    在做项目中,遇到导出excel表格时,银行账户号数字过长,导出的数字串变为计数法形式,如下图: 网上搜到解决方法,粘贴到这以供学习.不断更新. 原博地址:http://www.cnblogs.com/ ...

  6. Spring Boot下的一种导出CSV文件的代码框架

    1.前言 ​ CSV,逗号分隔值(Comma-Separated Values),即为逗号分隔的文本文件.如果值中含有逗号.换行符.制表符(Tab).单引号及双引号,则需要用双引号括起来:如果值中包含 ...

  7. Spring Boot 导出Excel表格

    Spring Boot 导出Excel表格 添加支持 <!--添加导入/出表格依赖--> <dependency> <groupId>org.apache.poi& ...

  8. spring mvc项目中导出excel表格简单实现

    查阅了一些资料,才整理出spring mvc 项目导出excel表格的实现,其实很是简单,小计一下,方便以后查阅,也希望帮助有需要的朋友. 1.导入所需要依赖(Jar包).我使用的是maven,所以坐 ...

  9. 在Spring Boot项目中使用Spock框架

    转载:https://www.jianshu.com/p/f1e354d382cd Spock框架是基于Groovy语言的测试框架,Groovy与Java具备良好的互操作性,因此可以在Spring B ...

  10. 在Spring Boot项目中使用Spock测试框架

    本文首发于个人网站:在Spring Boot项目中使用Spock测试框架 Spock框架是基于Groovy语言的测试框架,Groovy与Java具备良好的互操作性,因此可以在Spring Boot项目 ...

随机推荐

  1. CTF-CRYPTO-ECC(2)

    CTF-CRYPTO-ECC(2) 椭圆加密 4.BSGS(小步大步法) [HITCTF 2021 ] task.py #Elliptic Curve: y^2 = x^3 + 7 mod N whi ...

  2. QT5.14.1+Win7 64+Oracle11gR2 Qt连接数据库

    原文链接 1.QT5.14下OCI驱动编译完整步骤 1.安装qt的时候手动选择安装源码资源(默认不安装Source的) 2.进入QT安装目录下E:\Qt5.14\5.14.0\Src\qtbase\s ...

  3. AI 大模型:现状、挑战与未来多维度发展趋势

    在科技浪潮的推动下,以 Deepseek 为代表的 AI 大模型正以颠覆性力量重塑产业格局.从金融风控到工业质检,从智慧医疗到智能教育,这些轻量化的 AI 工具不仅打破了传统工作模式的桎梏,更构建起一 ...

  4. MongoDB 复制集机制及原理

    复制集的作用 MongoDB 复制集的主要意义在于实现服务高可用. 它的现实依赖于两个方面的功能: 数据写入时将数据迅速复制到另一个独立节点上 在接受写入的节点发生故障时自动选举出一个新的代替节点 在 ...

  5. AI 代理的未来是事件驱动的

    AI 代理即将彻底改变企业运营,它们具备自主解决问题的能力.适应性工作流以及可扩展性.但真正的挑战并不是构建更好的模型. 代理需要访问数据.工具,并且能够在不同系统之间共享信息,其输出还需要能被多个服 ...

  6. SpringBoot+Hutool 文件导出Excel

    Hutool-poi是针对Apache POI的封装,因此需要用户自行引入POI库,Hutool默认不引入.到目前为止,Hutool-poi支持: Excel文件(xls, xlsx)的读取(Exce ...

  7. 【Win32】VC6 Visual C/C++ 6.0 修改程序图标

    零.需求 就想给自己的C程序加个图标,好看些 一.解决 1.操作步骤 1.新建一个资源脚本 2.在新建的脚本上右键,选择插入 3.选择Icon,点新建或者引入,如果你没有准备图标点新建,有的话直接点引 ...

  8. Quartz.NET - 教程 12: Quartz 的其他特性

    译者注: 目录在这 Quartz.NET 3.x 教程 原文在这 Lesson 12: Miscellaneous Features of Quartz 插件 Quartz 提供了一个用于插入附加功能 ...

  9. Windows体验-注册表

    打开方式中关闭在应用商店查找关联应用 HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Explorer NoUseStoreOpenWit ...

  10. 青岛oj集训5

    Floyd算法--全源最短路 cerr:标准输出错误流:不会输出到freopen制定的out文件中,而是会输出到错误文件中. 提交上去无论加不加freopen,哪怕是提交到洛谷,也只是比较out文件中 ...