項目需求:上傳文件時如果有錯誤信息,則上傳不成功,需要提示用戶下載查看錯誤信息。下載查看錯誤信息是前端根據后台返回的對象數組放到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