ajax实现excel报表导出
利用AJAX实现Excel报表导出【解决乱码问题】 在项目开发里,导出Excel报表是个挺常见的需求。但场景一旦复杂起来,常规方法就容易碰壁。比如,接口需要Token认证,直接用A标签就行不通;页面交互复杂,表单提交的方式也不适用。这时候,前端采用AJAX请求、后端返回文件流的方案,就成了一个自然而
利用AJAX实现Excel报表导出【解决乱码问题】
在项目开发里,导出Excel报表是个挺常见的需求。但场景一旦复杂起来,常规方法就容易碰壁。比如,接口需要Token认证,直接用A标签就行不通;页面交互复杂,表单提交的方式也不适用。这时候,前端采用AJAX请求、后端返回文件流的方案,就成了一个自然而然的思路。
背景
具体来说,我们需要前端通过AJAX发起请求,后端设置好相应的响应头(Header),将Excel文件以二进制流的形式返回,再由前端触发浏览器下载。听起来流程清晰,但实际操作时,一个棘手的“乱码”问题却跳了出来。
第一版尝试:jQuery AJAX
主要代码
前端(jQuery AJAX)
var queryParams = {"test":"xxx"};
var url = "xxx";
$.ajax({
type : "POST", //提交方式
url : url,//路径
contentType: "application/json",
data: JSON.stringify(queryParams),
beforeSend: function (request) {
request.setRequestHeader("Authorization", "xxx");
},
success : function(result) {
const blob = new Blob([result], {type:"application/vnd.ms-excel"});
if(blob.size < 1) {
alert('导出失败,导出的内容为空!');
return
}
if(window.na vigator.msSa veOrOpenBlob) {
na vigator.msSa veOrOpenBlob(blob, 'test.xls')
} else {
const aLink = document.createElement('a');
aLink.style.display = 'none';
aLink.href = window.URL.createObjectURL(blob);
aLink.download = 'test.xls';
document.body.appendChild(aLink);
aLink.click();
document.body.removeChild(aLink);
}
}
});
后端(Spring Boot + EasyPOI)
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
@PostMapping(value = "/download")
public void downloadList(@RequestBody Objct obj, HttpServletResponse response) {
......
List excelList = new ArrayList<>();
// excel总体设置
ExportParams exportParams = new ExportParams();
// 指定sheet名字
exportParams.setSheetName("test");
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, Custom.class, excelList);
response.setContentType("application/vnd.ms-excel");
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("test", "utf-8") + ".xls");
OutputStream outputStream = response.getOutputStream();
workbook.write(outputStream);
outputStream.flush();
outputStream.close();
......
}
测试结果与问题定位
文件倒是能正常触发下载,但打开一看,内容全是乱码。问题出在哪儿?排查方向通常指向这么几个点:
1. 后端响应未正确设置字符编码,或者被Spring的过滤器统一处理了;
2. 前端页面本身的字符集设置有问题;
3. 最关键的一点,需要在AJAX请求中指定 responseType = “arraybuffer”,告诉浏览器期待一个二进制数组缓冲的响应。
经过一番测试,基本可以断定问题就出在第三点。然而,即便在jQuery的AJAX配置里加上了这个参数,乱码依然顽固地存在,问题并未解决。
第二版方案:原生AJAX
主要代码
既然jQuery的路子暂时走不通,那就回归本源,试试原生AJAX。后端代码保持不变。
var xhr = new XMLHttpRequest();
xhr.responseType = "arraybuffer";
xhr.open("POST", url, true);
xhr.onload = function () {
const blob = new Blob([this.response], {type:"application/vnd.ms-excel"});
if(blob.size < 1) {
alert('导出失败,导出的内容为空!');
return;
}
if(window.na vigator.msSa veOrOpenBlob) {
na vigator.msSa veOrOpenBlob(blob, 'test.xls')
} else {
const aLink = document.createElement('a');
aLink.style.display = 'none';
aLink.href = window.URL.createObjectURL(blob);
aLink.download = 'test.xls';
document.body.appendChild(aLink);
aLink.click();
document.body.removeChild(aLink);
return;
}
}
xhr.setRequestHeader("Authorization", "xxx");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify(queryParams));
测试结果
切换为原生AJAX并明确设置 xhr.responseType = "arraybuffer" 后,再次导出。这次下载的Excel文件打开清爽,乱码问题迎刃而解。
总结
问题的根源就在于对二进制流数据的处理方式上。设置 responseType 为 “arraybuffer” 是关键一步,它能确保浏览器正确解析后端返回的Excel文件流。从实践来看,这个参数在原生XMLHttpRequest中效果明确,直接生效。而在jQuery的AJAX方法中,由于封装层次的原因,相关配置可能未能完全生效,这也是一个需要注意的兼容性细节。希望这个踩坑经历和解决方案,能帮你顺利搞定AJAX导出Excel时的乱码难题。
Postman是一套面向API全生命周期的开发与测试平台,可在Mac上发送和调试多种协议请求,管理集合、环境及认证信息,并完成脚本测试、模拟服务、监控、文档发布和团队协作。它适合开发、测试及运维人员使用,提供个人免费方案。
Docker Desktop 是 Docker 官方为 Mac 提供的容器开发环境,集成 Docker Engine、命令行工具、Compose、Build、Kubernetes 与图形化管理界面。
Android Studio 是 Google 面向安卓应用开发提供的官方集成开发环境,基于 IntelliJ IDEA 构建。它整合智能代码编辑、Gradle 构建、界面预览、设备模拟、性能分析、调试测试及 APK 分析等工具。
Postman 是面向 API 全生命周期的开发与协作平台。Windows 桌面版可用于构建和发送 HTTP、GraphQL、gRPC、WebSocket、MQTT 等请求,并提供环境变量、集合、脚本测试、模拟服务、监控、文档及团队工作区等
Docker Desktop 为 Windows 开发者提供集成式容器环境,内置 Docker Engine、命令行工具、Compose、Build 与 Kubernetes 等组件,可在本机完成镜像构建、容器运行、日志查看和资源管理。
Android Studio 是 Google 面向 Android 应用开发提供的官方集成开发环境,以 IntelliJ IDEA 为基础,集成智能代码编辑、Gradle 构建、设备模拟、界面预览、调试测试及性能分析工具,













