SpringBoot+Vue下载Excel文件流(No converter、Excel乱码)
目录介绍No converterExcel乱码正确代码后端代码前端代码介绍后端使用SpringBoot、Mybatis Plus,前端使用Vue,进行Excel文件下载。后端使用了Hutool工具提供的Excel文件流下载。No converter问题:后端控制台出现No converter for [class com.common.lang.Result] with preset Conten
介绍
后端使用SpringBoot、Mybatis Plus,前端使用Vue,进行Excel文件下载。
后端使用了Hutool工具提供的Excel文件流下载。
No converter
问题:
后端控制台出现No converter for [class com.common.lang.Result] with preset Content-Type 'application/vnd.ms-excel;charset=utf-8'
的错误
处理:
原来的代码返回一个对象(包含code、message、data等)。
public Result download (HttpServletResponse response) throws IOException {
//省略
return Result.succ("success");
}
改为:
public void download (HttpServletResponse response) throws IOException {
//省略
return;
}
就是把返回的参数类型设置为void,身为小白的我并不清楚原因。
Excel乱码
前端下载的Excel打开后出现:
于是参考:
https://www.cnblogs.com/yixiaoyang-/p/13042540.html
https://www.cnblogs.com/cynthia-wuqian/p/7927621.html
才得到了正确结果(测试数据):
正确代码
后端代码
关于Excel的操作可参考Hutool工具提供的Excel文件流下载,比如可以设置文件格式为xls或者xlsx。
@RequestMapping("/download")
public void download (@RequestBody Map<String, Object> columnMap,
HttpServletResponse response) throws IOException {
List<String> row1 = CollUtil.newArrayList("aa", "bb", "cc", "dd");
ExcelWriter writer = ExcelUtil.getWriter();
writer.write(row1, true);
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition","attachment;filename=test.xls");
ServletOutputStream out=response.getOutputStream();
writer.flush(out, true);
writer.close();
IoUtil.close(out);
return;
}
前端代码
方法1
其中responseType
可以设置为arraybuffer
或者blob
,必须要设置一个。
elink.download
后面的文件名可以随意设置(可中文),可以和后端的文件名不一样,最终会以前端设置的文件名为准,但文件后缀要和后端的xls或xlsx保持一致。
axios({
baseURL: "http://localhost:8081/",
url: "download",
method: "post",
data: data,
// responseType: "arraybuffer", //可以使用arraybuffer
responseType: "blob", //也可以使用blob
})
.then((res) => {
console.log(res);
if (res) {
let blob = new Blob([res.data], {
type: "application/vnd.ms-excel;charset=utf-8",
}); // res就是接口返回的文件流了
let objectUrl = URL.createObjectURL(blob);
const elink = document.createElement("a");
elink.download = "下载文件名称.xls"; //下载文件名称,
elink.style.display = "none";
elink.href = objectUrl;
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href); // 释放URL 对象
document.body.removeChild(elink);
}
})
.catch(function (error) {
console.log(error);
});
方法2
axios({
baseURL: "http://localhost:8081/",
url: "download",
method: "post",
data: data,
// responseType: "arraybuffer",//可以使用arraybuffer
responseType: "blob", //也可以使用blob
})
.then((res) => {
console.log(res);
if (res) {
let blob = new Blob([res.data], {
type: "application/vnd.ms-excel",
}); // res就是接口返回的文件流了
let objectUrl = URL.createObjectURL(blob);
window.location.href = objectUrl;
}
})
.catch(function (error) {
console.log(error);
});
代码行数减少了,但此时无法设置文件名:
里面的内容是正确的。
方法3
先引入一个包js-file-download:
cnpm install js-file-download --save
使用方法:
var fileDownload = require('js-file-download');
fileDownload(data, '文件名称.xls');
具体代入就是:
axios({
baseURL: "http://localhost:8081/",
url: "download",
method: "post",
data: data,
// responseType: "arraybuffer",//可以使用arraybuffer
responseType: "blob", //也可以使用blob
})
.then((res) => {
console.log(res);
if (res) {
var fileDownload = require("js-file-download");
fileDownload(res.data, "新方式.xls");
}
})
.catch(function (error) {
console.log(error);
});
与方法一相比,代码更简洁明了,只需要设置文件名。
更多推荐
所有评论(0)