项目需求:上传文件时如果有错误信息,则上传不成功,需要提示用户下载查看错误信息。下载查看错误信息是前端根据后台返回的对象数组放到excel表格中的。
后台返回的数组:
效果如下:
在开始之前先要了解一下几个excel格式的区别:
1.后缀是xls的在2007版本之后的office打开会有提示(xls在wps上打开没有提示)
2.后缀是xlsx在2007版本之后的打开没有提示,但是在2007之前的版本会打不开
3.csv是最通用的一种文件格式,它可以非常容易的被导入各种pc表格及数据库中,此文件中一行即为数据表的一行。生成数据表字段用半角逗号隔开。但是csv不能设置样式。
第一种:生成xls
可粘贴的代码如下:
// 错误信息下载 exportEx = val => { let JSONData = val; let ShowLabel = [\'序号\', \'imei\', \'错误原因\']; //先转化json let arrData = typeof JSONData != \'object\' ? JSON.parse(JSONData) : JSONData; // 给数组内容换好位置 let finalData = []; arrData.forEach(item => { let obj = { rowNum: item.rowNum, imei: item.imei ? item.imei : \'\', errorMsg: item.errorMsg, }; finalData.push(obj); }); let excel = \'<table>\'; //设置表头 let row = \'<tr>\'; for (let i = 0; i < ShowLabel.length; i++) { row += \'<td>\' + ShowLabel[i] + \'</td>\'; } //换行 excel += row + \'</tr>\'; //设置数据 for (let i = 0; i < finalData.length; i++) { let row = \'<tr>\'; for (let index in finalData[i]) { let value = finalData[i][index]; if (index === \'imei\') { // 当数字超过一定长度就科学计数法可以使用style=\'mso-number-format:"\@"\' // 这个属性指定某单元格的数据格式,避免Excel自动转换格式 row += `<td style=\'mso-number-format:\"\\@\"\'>${value}</td>`; } else { row += \'<td>\' + value + \'</td>\'; } } excel += row + \'</tr>\'; } excel += \'</table>\'; let excelFile = "<html xmlns:o=\'urn:schemas-microsoft-com:office:office\' xmlns:x=\'urn:schemas-microsoft-com:office:excel\' xmlns=\'http://www.w3.org/TR/REC-html40\'>"; excelFile += \'<meta http-equiv="content-type" content="application/vnd.ms-excel; charset=UTF-8">\'; excelFile += \'<meta http-equiv="content-type" content="application/vnd.ms-excel\'; excelFile += \'; charset=UTF-8">\'; excelFile += \'<head>\'; excelFile += \'<!--[if gte mso 9]>\'; excelFile += \'<xml>\'; excelFile += \'<x:ExcelWorkbook>\'; excelFile += \'<x:ExcelWorksheets>\'; excelFile += \'<x:ExcelWorksheet>\'; excelFile += \'<x:Name>\'; excelFile += \'{worksheet}\'; excelFile += \'</x:Name>\'; excelFile += \'<x:WorksheetOptions>\'; excelFile += \'<x:DisplayGridlines/>\'; excelFile += \'</x:WorksheetOptions>\'; excelFile += \'</x:ExcelWorksheet>\'; excelFile += \'</x:ExcelWorksheets>\'; excelFile += \'</x:ExcelWorkbook>\'; excelFile += \'</xml>\'; excelFile += \'<![endif]-->\'; excelFile += \'</head>\'; excelFile += \'<body>\'; excelFile += excel; excelFile += \'</body>\'; excelFile += \'</html>\'; let uri = \'data:application/vnd.ms-excel;charset=utf-8,\' + encodeURIComponent(excelFile); let link = document.createElement(\'a\'); link.href = uri; link.style = \'visibility:hidden\'; link.download = \'错误数据文件.xls\'; document.body.appendChild(link); link.click(); document.body.removeChild(link); message.success(\'下载成功!\'); this.setState({ errorMsgVisible: false, }); };
补充:在导出的excel中较长的数字会变成科学计数法展示,为了让过长的数字全部展示出来需要添加样式:style="mso-number-format:\'\@\';"
在代码中"\@"中的引号和反斜杠都需要添加转义符才能使用。
第二种:生成xlsx
需要引入js-xlsx插件
1.使用npm install xlsx
2.并在文件中引入 import XLSX from \'xlsx\';
可复制的代码如下:
// 错误信息下载 exportEx = val => { let JSONData = val; let ShowLabel = [\'序号\', \'imei\', \'错误原因\']; //先转化json let arrData = typeof JSONData != \'object\' ? JSON.parse(JSONData) : JSONData; // 给数组内容换好位置 let finalData = []; arrData.forEach(item => { let obj = { rowNum: item.rowNum, imei: item.imei ? item.imei : \'\', errorMsg: item.errorMsg, }; finalData.push(obj); }); let excel = \'<table>\'; //设置表头 let row = \'<tr>\'; for (let i = 0; i < ShowLabel.length; i++) { row += \'<td>\' + ShowLabel[i] + \'</td>\'; } //换行 excel += row + \'</tr>\'; //设置数据 for (let i = 0; i < finalData.length; i++) { let row = \'<tr>\'; for (let index in finalData[i]) { let value = finalData[i][index]; if (index === \'imei\') { // 当数字超过一定长度就科学计数法可以使用style=\'mso-number-format:"\@"\' // 这个属性指定某单元格的数据格式,避免Excel自动转换格式 row += `<td style=\'mso-number-format:\"\\@\"\'>${value}</td>`; } else { row += \'<td>\' + value + \'</td>\'; } } excel += row + \'</tr>\'; } excel += \'</table>\'; // 因为我们这里的数据是string格式的,但是js-xlsx需要dom格式,则先新建一个div然后把数据加入到innerHTML中,在传childNodes[0]即使dom格式的数据 let objE = document.createElement(\'div\'); objE.innerHTML = excel; // 将一个table对象转换成一个sheet对象,raw为true的作用是把数字当成string,身份证不转换成科学计数法 let sheet = XLSX.utils.table_to_sheet(objE.childNodes[0], { raw: true }); this.openDownloadDialog(this.sheet2blob(sheet, \'错误数据文件\'), \'错误数据文件.xlsx\'); }; sheet2blob = (sheet, sheetName) => { sheetName = sheetName || \'sheet1\'; // 不存在sheetName时使用sheet1代替 let workbook = { SheetNames: [sheetName], Sheets: {}, }; workbook.Sheets[sheetName] = sheet; // 生成excel的配置项 let wopts = { bookType: \'xlsx\', // 要生成的文件类型 bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性 type: \'binary\', // 二进制格式 }; let wbout = XLSX.write(workbook, wopts); let blob = new Blob([this.s2ab(wbout)], { type: \'application/octet-stream\', }); // 字符串转ArrayBuffer return blob; }; s2ab = s => { let buf = new ArrayBuffer(s.length); let view = new Uint8Array(buf); for (let i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff; return buf; }; openDownloadDialog = (url, saveName) => { if (typeof url === \'object\' && url instanceof Blob) { url = URL.createObjectURL(url); // 创建blob地址 } let aLink = document.createElement(\'a\'); aLink.href = url; aLink.download = saveName || \'\'; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效 let event; if (window.MouseEvent) event = new MouseEvent(\'click\'); else { event = document.createEvent(\'MouseEvents\'); event.initMouseEvent( \'click\', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null ); } aLink.dispatchEvent(event); message.success(\'下载成功!\'); this.setState({ errorMsgVisible: false, }); };
第二种:生成csv
参考链接:https://blog.csdn.net/qq_35493664/article/details/88896638?utm_medium=distribute.pc_relevant_download.none-task-blog-BlogCommendFromBaidu-1.nonecase&depth_1-utm_source=distribute.pc_relevant_download.none-task-blog-BlogCommendFromBaidu-1.nonecas