1、在请求时指定响应类型
//导出excel exportExcel(data) { return request({ url: '/api/route/export', method: 'post', data, responseType: 'arraybuffer', }) },
2、将数据写入输出流中
@PostMapping("/export") public Result exportInfo(@RequestBody JSONObject jsonObject, HttpServletResponse response) throws IOException { //根据条件查询数据 List<Route> list = routeService.selectPage(jsonObject); if(CollectionUtils.isEmpty(list)){ return Result.error(20001,"没有数据"); } if(list.size() > maxExportTotal){ return Result.error(20001,"导出的数据过大,请输入条件后导出"); } ExcelUtils.exportExcel(list, jsonObject.getString("fileName"),jsonObject.getString("fileName"), Route.class,
jsonObject.getString("fileName"), response); return null; }
public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
sos.write("你好".getBytes("utf-8"));
private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) throws IOException { try { response.setCharacterEncoding("UTF-8"); response.setHeader("content-Type", "application/vnd.ms-excel"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xlsx", "UTF-8"));
// 将数据写入到输出流中
workbook.write(response.getOutputStream()); } catch (Exception e) { throw new IOException(e.getMessage()); } }
3、前端使用fileDownload下载
//导出数据 exportExcel() { this.downloadLoading = true const fileName = '线路数据导出' route.exportExcel({ fileName, siteName: this.listQuery.siteName, routeName: this.listQuery.routeName }).then(res => { console.log(res) fileDownload(res, fileName + '.xlsx') }, err => { console.log(err) } ).finally(()=>{ this.downloadLoading = false }) }, }
注意:此处是res还是res.data要看前端的request.js中响应拦截器是否进行了处理
// response interceptor service.interceptors.response.use( response => { const headers = response.headers let res = response.data // 此类为下载流文件,不拦截 if (headers['content-type'] === 'application/octet-stream;charset=utf-8') { return res } if (headers['content-type'] === 'arrayBuffer;charset=UTF-8') { return res } if (headers['content-type'] === 'application/vnd.ms-excel;charset=UTF-8') { return res } if (response.request.responseType === 'arraybuffer') { const enc = new TextDecoder('utf-8') res = JSON.parse(enc.decode(new Uint8Array(res))) } // if the custom code is not 20000, it is judged as an error. if (res.code !== 20000) { Message({ message: res.msg || 'Error', type: 'error', duration: 5 * 1000 }) // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired; if (res.code === 50008 || res.code === 50012 || res.code === 50014) { // to re-login MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', { confirmButtonText: 'Re-Login', cancelButtonText: 'Cancel', type: 'warning' }).then(() => { store.dispatch('user/resetToken').then(() => { location.reload() }) }) } return Promise.reject(new Error(res.msg || 'Error')) } else { return res } }, error => { console.log('err' + error) // for debug Message({ message: error.msg, type: 'error', duration: 5 * 1000 }) return Promise.reject(error) } )