vben admin 做列表导出,第一次用vue3,导出搞了很久,网上找了很多资料,都基本一样,我这里记录一下关键点,让需要的朋友能用上。
1.后台java
@ResponseBody
@RequestMapping(value = "/exportUser.do")
public void exportUser(String firstParamName , String firstParamValue ,String secondParamName ,String secondParamValue ,
String secondParamValue2 ,String flag,Integer deleteType,HttpServletResponse response)throws IOException{
XSSFWorkbook book = new XSSFWorkbook();
ResponseInfo info = new ResponseInfo();
Calendar instance = Calendar.getInstance();
int year = instance.get(Calendar.YEAR);
int month = instance.get(Calendar.MARCH)+1;
int date = instance.get(Calendar.DAY_OF_MONTH);
String timeStr = year+"-"+month+"-"+ date;
String fileName = "";
fileName = "名称" + timeStr;// 生成的excel的名字;
CommonParamsVm commonParamsVm = new CommonParamsVm();
commonParamsVm.setFirstParamName(firstParamName);
commonParamsVm.setFirstParamValue(firstParamValue);
commonParamsVm.setSecondParamName(secondParamName);
commonParamsVm.setSecondParamValue(secondParamValue);
commonParamsVm.setSecondParamValue2(secondParamValue2);
commonParamsVm.setFlag(flag);
commonParamsVm.setDeleteType(deleteType);
List<CustomerSalesIntention> list = customerSalesIntentionService.getListByCondition(commonParamsVm);
LinkedHashMap<String, String> hashMap = new LinkedHashMap<>();
hashMap.put("intentionTheme","主题");
JSONArray jSONArray= JSONArray.parseArray(JSON.toJSONString(list));
book.write(ExcelUtils.downloadExcelFileVue3(fileName, hashMap, jSONArray, response));
book.close();
}
public static ServletOutputStream downloadExcelFileVue3(String title,Map<String,String> headMap,JSONArray ja,HttpServletResponse response){
ServletOutputStream outputStream =null;
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
ExcelUtils.exportExcelX(title,headMap,ja,null,0,os);
byte[] content = os.toByteArray();
InputStream is = new ByteArrayInputStream(content);
// 设置response参数,可以打开下载页面
response.reset();
/* response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename="+ new String((title + ".xlsx").getBytes(), StandardCharsets.ISO_8859_1));
*/
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
response.setHeader("Content-Disposition", "attachment; filename=" + title + ".xlsx");
response.setContentLength(content.length);
outputStream = response.getOutputStream();
BufferedInputStream bis = new BufferedInputStream(is);
BufferedOutputStream bos = new BufferedOutputStream(outputStream);
byte[] buff = new byte[8192];
int bytesRead;
while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
bis.close();
bos.close();
outputStream.flush();
outputStream.close();
}catch (Exception e) {
e.printStackTrace();
}
return outputStream;
}
后台关键点, book.write 给二进制流返回给浏览器,接口返回的
2前端,vue3的代码(框架vben admin)
export function exportClient(params: any) {
return defHttpIgen
.get<any>({
url: Api.GETEXCElDATA,
params: {
...params,
deleteType: 0,
},
responseType: 'blob', // 返回文件的类型
})
.then((response) => {
const blob = new Blob([response], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
}); //保存为xlsx格式的excel文件
const objectUrl = window.URL.createObjectURL(blob);
const a = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none';
a.href = objectUrl;
a.download = '表单名称';
a.click();
document.body.removeChild(a);
});
}
这个地方关键点,就是 responseType: 'blob',
那下面就来了问题了,这样写,肯定是没问题的,可是在这个框架上会遇到,
返回时undefined,就无法下载,解决办法
框架数据返回的地方,加上这个,就可以了,因为我们的数据返回是必须 const { code, result, message } = data; ,而文件是流的,就不能这样返回了,最后成功