基于Java、Js导出Execl通用模板
需求:批量导出不同表格的数据,每个表格的数据不一样,字段不一样,用最简单的方式实现导出Execl通用模板
效果图:

一、前端
1.1、前端代码
<button id="export" onclick="exportData();return false; "> <span class="icon_export">导出</span></button>
// 导出
function exportData() {
top.Dialog.alert("数据正在生成中,请耐心等待...!");
// Get方式请求后台,参数后台通过HttpServletRequest获取
window.open(getBaseUrl() + "/khzpf/exportXxxxErroInfo?rqdm=" + params.rqdm + "&rpfxdm=" + params.rpfxdm);
}
/*
备注:
这种方式也可以实现
出现的问题:但是多次操作会出现,$('#myFormId')[0] == 'undefined'的情况,询问DeepSeek:回答表格有防止重复提交的功能,所以只可以点击一次,DeepSeek提供的方式没有解决去除表格防止重复的功能,但是实际业务可能多次点击,所以暂时把代码放在这里
*/
$('#myFormId').attr("action", getBaseUrl() + "/khzpf/exportXxxxxxxErroInfo?rqdm=" + params.rqdm + "&rpfxdm=" + params.rpfxdm);
$('#myFormId').submit();
// 重置表单(可选)
setTimeout(() => { $('#myFormId')[0].reset() }, 1000);
1.2、题外话:前端制作通用列表显示内容
// 1002 "每周一次自动粮情检测 "
const columns1002 = [
{ display: '序号', name: 'xh', align: 'center', width: "10%", isSort: false, showTitle: true },
{ display: '1002标题列1', name: 'value1', align: 'center', width: "20%", isSort: false, showTitle: true },
{ display: '1002标题列2', name: 'value2', align: 'center', width: "20%", isSort: false, showTitle: true },
{ display: '1002标题列3', name: 'value3', align: 'center', width: "20%", isSort: false, showTitle: true },
{ display: '1002标题列4', name: 'value4', align: 'center', width: "20%", isSort: false, showTitle: true }
]
// 1003 出入库业务每笔必须有地磅抓拍图片
const columns1003 = [
{ display: '序号', name: 'xh', align: 'center', width: "10%", isSort: false, showTitle: true },
{ display: '1003标题列1', name: 'value1', align: 'center', width: "10%", isSort: false, showTitle: true },
{ display: '1003标题列2', name: 'value2', align: 'center', width: "10%", isSort: false, showTitle: true },
{ display: '1003标题列3', name: 'value3', align: 'center', width: "10%", isSort: false, showTitle: true },
{ display: '1003标题列4', name: 'value4', align: 'center', width: "10%", isSort: false, showTitle: true },
{ display: '1003标题列5', name: 'value5', align: 'center', width: "10%", isSort: false, showTitle: true }
]
// 方案2:使用对象容器(推荐更安全的模式)
const columnsConfig = {
1002: columns1002,
1003: columns1003
}
//加载表格数据
grid = $("#dataBasic").quiGrid({
columns: columnsConfig[rpfxdmStr]
});
二、后端
2.1、pom
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>3.2.0</version>
</dependency>
2.2、后台代码
/**
* 导出方法
* @param request 前端请求
* @param response 请求返回
* @throws IOException 异常
*/
@GetMapping(value = "/exportXxxxxxxErroInfo")
public void exportXxxxxxxErroInfo(HttpServletRequest request, HttpServletResponse response) throws IOException {
try {
// 1. 前台参数校验
String rpfxdm = request.getParameter("rpfxdm");
String rqdm = request.getParameter("rqdm");
if (StringUtils.isEmpty(rpfxdm) || StringUtils.isEmpty(rqdm)) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "参数 rpfxdm 或 rqdm 不能为空");
return;
}
// 2. 获取用户信息和文件名称
TbSysUserInfo userInfo = UserInfoUtil.getUserInfo();
// 默认文件名称
String pfx = "文件详情";
TbAssKhzpfmb detail = tbAssKhzpfmbService.detail(rpfxdm);
if (detail != null && detail.getPfx() != null) {
pfx = detail.getPfx();
}
// 3. 创建导出参数,第二行显示
/*
* 三个参数
* title Sheet页主页的标题名称,第一行显示
* secondTitle 第二行显示的标题名称,这里显示的是导出人(操作人)
* String sheetName Sheet页的名称
*/
ExportParams exportParams = new ExportParams(pfx, "导出人:" + userInfo.getFullname(), pfx);
exportParams.setStyle(ExcelStyleType.BORDER.getClazz());
// 4. 生成 Workbook 并设置响应
/*
response.setContentType("application/vnd.ms-excel");
作用:在 Java Web 开发中用于设置 HTTP 响应的 MIME 类型,指定浏览器应该如何处理返回的文件。
1、指定响应类型:
将 HTTP 响应的内容类型(Content-Type)设置为 application/vnd.ms-excel,告诉浏览器返回的数据是一个 Excel 文件(通常是 .xls 文件),并应按照 Excel 文件进行处理。
2、提示浏览器下载 Excel 文件:
当浏览器接收到这个响应时,它会识别到这个 MIME 类型,并自动提示用户下载 Excel 文件或者在支持的浏览器中以 Excel 格式打开文件。
3、Excel 文件格式:
application/vnd.ms-excel 是 Microsoft Excel 文件的 MIME 类型,表示文件是一个 Excel 表格,通常为 .xls 后缀。
如果你想返回一个 .xlsx 文件(Excel 2007及以后版本),则可以使用 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet。
*/
response.setContentType("application/vnd.ms-excel");
// 文件名
String fileName = pfx + "_文件详情.xls";
// 使用URLEncoder对文件名进行UTF-8编码,并替换加号为%20。
// 这是因为URLEncoder会将空格转换为加号,但在HTTP头中,空格应该被编码为%20。
String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
// 设置Content-Disposition响应头,指定附件的文件名。
// 使用filename*=UTF-8''前缀告诉浏览器该文件名是UTF-8编码的。
// encodedFileName变量已经处理过加号的问题,确保文件名正确无误。
response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + encodedFileName);
// 5. 使用 try-with-resources 确保资源释放
/*
try-with-resources 的自动关闭机制
作用:代码中声明的 Workbook 和 ServletOutputStream 会在 try 块执行完毕后自动调用 close() 方法,无论代码是否正常执行或抛出异常
在try 块结束后,out 和 workbook 会按声明顺序的逆序关闭(即先关闭 out,再关闭 workbook),确保资源释放
前提条件:资源必须实现 AutoCloseable 接口。
例如: Apache POI 的 Workbook(如 XSSFWorkbook 或 HSSFWorkbook)实现了 AutoCloseable,支持自动关闭。
ServletOutputStream 是 Servlet 规范中的类,通常也实现了 Closeable(AutoCloseable 的子接口)
*/
try (Workbook workbook = getWorkbookByKqdm(exportParams, rpfxdm, rqdm);
ServletOutputStream out = response.getOutputStream()) {
// 将 Workbook 中的 Excel 数据写入输出流,客户端会收到文件内容
workbook.write(out);
}
} catch (Exception e) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "导出失败,请稍后重试");
log.error("==导出异常==");
e.printStackTrace();
}
}
/**
* 获取通用Workbook对象
* 关键步骤:
* 可以将字段中文名,字段名,字段显示长度,填入代码,不需要编写Vo实体类:columns.add(new ExcelExportEntity("序号", "xh", 10));
* @param exportParams 导出参数
* @param rpfxdm 区分不同查询结果实体类的字段
* @param rqdm 参数
* @return
*/
private Workbook getWorkbookByKqdm(ExportParams exportParams, String rpfxdm, String rqdm){
List<Map<String,String>> socreDataResult = tbAssKhzpfService.getScoreData(rpfxdm, rqdm);
List<ExcelExportEntity> columns = new ArrayList<>();
switch (rpfxdm) {
case "1002":
columns.add(new ExcelExportEntity("序号", "xh", 10));
columns.add(new ExcelExportEntity("1002标题列1", "value1", 20));
columns.add(new ExcelExportEntity("1002标题列2", "value2", 20));
columns.add(new ExcelExportEntity("1002标题列3", "value3", 20));
columns.add(new ExcelExportEntity("1002标题列4", "value4", 20));
break;
case "1003":
columns.add(new ExcelExportEntity("序号", "xh", 10));
columns.add(new ExcelExportEntity("1003标题列1", "value1", 20));
columns.add(new ExcelExportEntity("1003标题列2", "value2", 20));
columns.add(new ExcelExportEntity("1003标题列3", "value3", 20));
columns.add(new ExcelExportEntity("1003标题列4", "value4", 20));
columns.add(new ExcelExportEntity("1003标题列5", "value4", 20));
break;
default:
// 默认情况处理
break;
}
return ExcelExportUtil.exportExcel(exportParams, columns, socreDataResult);
}

浙公网安备 33010602011771号