Java Hutool ExcelUtil工具类封装:导出、读取与合并单元格
解决Java开发中Excel导入导出的常见需求,通过Hutool的ExcelUtil封装导出下载、数据读取及合并单元格的核心功能,提供可直接复用的工具类代码。
依赖准备
在使用 Hutool 进行 Excel 操作前,需引入核心包及 Apache POI 依赖。建议根据项目实际版本调整依赖声明。
第1步:添加 Maven 依赖
- 目的:获取 Hutool 核心能力及 Excel 处理底层支持。
- 入口:pom.xml 文件。
- 动作:添加以下
dependency节点。
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.4.M1</version></dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.0.0</version></dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-full</artifactId>
<version>5.0.0</version></dependency>
基础工具类封装
以下工具类 ExcelUtils 封装了三种常用场景:仅导出空模板、导出数据与表头、以及读取上传的 Excel 文件。代码基于 Spring Web 环境编写,支持响应流直接输出。
package io.supers.common.utils;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.style.StyleUtil;
import io.supers.framework.em.BaseErrorEnum;
import io.supers.framework.exception.RRException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* Excel 工具类
*
* @author guoc
* @date 2022年05月31日 下午 17:21
*/
public class ExcelUtils {
/**
* 下载 Excel 模板 (只有表头的 Excel)
*
* @param response response
* @param headers 表头
* @param fileName 文件名
*/
public static void exportHeaders(HttpServletResponse response, List<String> headers, String fileName) {
export(response, null, headers, fileName);
}
/**
* 导出或下载 Excel 公用方法
*
* @param response 当前请求的 HttpServletResponse
* @param rows 需要写入的数据 List
* @param fileName 最终文件名
*/
public static void export(HttpServletResponse response, List<Map<String, Object>> rows, List<String> headers, String fileName) {
// 获取 Writer
ExcelWriter writer = ExcelUtil.getWriter(true);
// 写入表头
writer = writer.writeHeadRow(headers);
// 若是有数据 则写入数据
if (CollectionUtils.isNotEmpty(rows)) {
writer.write(rows);
}
Workbook workbook = writer.getWorkbook();
CellStyle defaultCellStyle = StyleUtil.createDefaultCellStyle(workbook);
DataFormat format = writer.getWorkbook().createDataFormat();
// 默认为 文本格式
defaultCellStyle.setDataFormat(format.getFormat("@"));
// 默认为 居中
defaultCellStyle.setAlignment(HorizontalAlignment.CENTER);
for (int i = 0; i < headers.size(); i++) {
String h = headers.get(i);
h = h == null ? " " : h;
writer.setColumnStyle(i, defaultCellStyle);
// 默认宽度为 3 * 表头字符数
writer.setColumnWidth(i, 3 * h.length());
}
try {
// 弹出下载对话框的文件名,不能为中文,中文请自行编码
fileName = URLUtil.encode(fileName);
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
response.setContentType(ExcelUtil.XLSX_CONTENT_TYPE);
// 输出
ServletOutputStream out = response.getOutputStream();
writer.flush(out, true);
// 关闭writer,释放内存
writer.close();
//此处记得关闭输出Servlet流
IoUtil.close(out);
} catch (IOException e) {
e.printStackTrace();
throw new RRException(BaseErrorEnum.COMMON_ERROR, "下载文件失败!\n" + e.getMessage());
}
}
/**
* 读取上传到后台的excel
*
* @param file MultipartFile 上传的文件
* @return 数据列表
* @throws IOException e
*/
public static List<Map<String, Object>> readExcelRows(MultipartFile file) throws IOException {
return ExcelUtil.getReader(file.getInputStream()).readAll();
}
}
关键参数说明:
export方法中,rows接受List<Map<String, Object>>类型,便于动态映射字段。fileName在 HTTP 响应头中需进行 URL 编码以支持中文文件名。readExcelRows将 Excel 内容直接转换为 Map 列表,简化后续业务处理。
复杂表头与合并单元格处理
当需要生成包含合并单元格的复杂 Excel 时,可利用 ExcelWriter 提供的 merge 方法。该方法允许指定起始行/列与结束行/列范围进行合并。
第1步:调用 merge 方法合并单元格
- 目的:在特定区域内合并单元格并填入标题或标识。
- 入口:
ExcelWriter实例。 - 动作:遍历数据结构,计算合并范围后调用
merge。
// cn.hutool.poi.excel.ExcelWriter#merge(int, int, int, int, java.lang.Object, boolean)
/**
* 合并某行的单元格,并写入对象到单元格<br>
* 如果写到单元格中的内容非null,行号自动+1,否则当前行号不变<br>
* 样式为默认标题样式,可使用{@link #getHeadCellStyle()}方法调用后自定义默认样式
*
* @param firstRow 起始行,0开始
* @param lastRow 结束行,0开始
* @param firstColumn 起始列,0开始
* @param lastColumn 结束列,0开始
* @param content 合并单元格后的内容
* @param isSetHeaderStyle 是否为合并后的单元格设置默认标题样式,只提取边框样式
* @return this
* @since 4.0.10
*/
public ExcelWriter merge(int firstRow, int lastRow, int firstColumn, int lastColumn, Object content, boolean isSetHeaderStyle) {
Assert.isFalse(this.isClosed, "ExcelWriter has been closed!");
CellStyle style = null;
if (null != this.styleSet) {
style = styleSet.getStyleByValueType(content, isSetHeaderStyle);
}
return merge(firstRow, lastRow, firstColumn, lastColumn, content, style);
}
应用策略:
- 动态表头:若表头不固定,可先构建
List<String>动态生成列名,再传入导出方法。 - 规律合并:对于有重复值或多层级结构的列,可在遍历数据时识别边界,调用
merge完成视觉上的分组效果。
总结
上述封装覆盖了绝大多数 Java Excel 导入导出场景。对于简单表格,直接使用 ExcelUtil 配合 Map 集合即可快速实现;对于复杂报表,结合 merge 方法可实现灵活的布局。若需操作 Java Bean 对象,建议在数据层增加一层 Converter 转换逻辑,保持工具类的通用性。
以上就是关于Java Hutool ExcelUtil工具类封装导出的详细内容,更多关于Java Hutool实用技巧的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









