js 前端實現將json格式數組下載到excel(xls、xlsx、csv)表格里


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM