js 導出多sheet表格


原文github地址:https://github.com/wangyunhui1993/neo-export-excel

var tablesToExcel = (function () {
  var uri = "data:application/vnd.ms-excel;base64,",
    html_start = `<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40">`,
    template_ExcelWorksheet = `<x:ExcelWorksheet><x:Name>{SheetName}</x:Name><x:WorksheetSource HRef="sheet{SheetIndex}.htm"/></x:ExcelWorksheet>`,
    template_ListWorksheet = `<o:File HRef="sheet{SheetIndex}.htm"/>`,
    style = `<style type="text/css">
    table th{text-align: center;font-weight: bold;font-size:16px;background-color: #559EC6;color:#fff;height:30px;}
    table td{text-align: center;font-size:16px;}
    </style>`,
    template_HTMLWorksheet =
      `
------=_NextPart_dummy
Content-Location: sheet{SheetIndex}.htm
Content-Type: text/html; charset=utf-8
` +
      html_start +
      `
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <link id="Main-File" rel="Main-File" href="../WorkBook.htm">
    <link rel="File-List" href="filelist.xml">
    ${style}
</head>
<body><table  border="1">{SheetContent}</table></body>
</html>`,
    template_WorkBook =
      `MIME-Version: 1.0
X-Document-Type: Workbook
Content-Type: multipart/related; boundary="----=_NextPart_dummy"
------=_NextPart_dummy
Content-Location: WorkBook.htm
Content-Type: text/html; charset=utf-8
` +
      html_start +
      `
<head>
<meta name="Excel Workbook Frameset">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="File-List" href="filelist.xml">
<!--[if gte mso 9]><xml>
 <x:ExcelWorkbook>
    <x:ExcelWorksheets>{ExcelWorksheets}</x:ExcelWorksheets>
    <x:ActiveSheet>0</x:ActiveSheet>
 </x:ExcelWorkbook>
</xml><![endif]-->
</head>
<frameset>
    <frame src="sheet0.htm" name="frSheet">
    <noframes><body><p>This page uses frames, but your browser does not support them.</p></body></noframes>
</frameset>
</html>
{HTMLWorksheets}
Content-Location: filelist.xml
Content-Type: text/xml; charset="utf-8"
<xml xmlns:o="urn:schemas-microsoft-com:office:office">
    <o:MainFile HRef="../WorkBook.htm"/>
    {ListWorksheets}
    <o:File HRef="filelist.xml"/>
</xml>
------=_NextPart_dummy--
`,
    base64 = function (s) {
      return window.btoa(unescape(encodeURIComponent(s)));
    },
    format = function (s, c) {
      return s.replace(/{(\w+)}/g, function (m, p) {
        return c[p];
      });
    };
  return function (tables, filename) {
    var context_WorkBook = {
      ExcelWorksheets: "",
      HTMLWorksheets: "",
      ListWorksheets: "",
    };
    tables.forEach((item, index) => {
      var SheetName = item.name || `sheet${index + 1}`;
      context_WorkBook.ExcelWorksheets += format(template_ExcelWorksheet, {
        SheetIndex: index,
        SheetName: SheetName,
      });
      context_WorkBook.HTMLWorksheets += format(template_HTMLWorksheet, {
        SheetIndex: index,
        SheetContent: item.html,
      });
      context_WorkBook.ListWorksheets += format(template_ListWorksheet, {
        SheetIndex: index,
      });
    });
    console.log(
      "context_WorkBook",
      format(template_WorkBook, context_WorkBook)
    );
    var link = document.createElement("A");
    link.href = uri + base64(format(template_WorkBook, context_WorkBook));
    link.download = filename || "Workbook.xls";
    link.target = "_blank";
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  };
})();
/* var sheet_1 = `<thead><tr><th>這是sheet1的表頭</th></tr><thead><tbody><tr><td>這是sheet1的表體</td></tr><tbody>`
var sheet_2 = `<thead><tr><th>這是sheet2的表頭</th></tr><thead><tbody><tr><td>這是sheet2的表體</td></tr><tbody>`
var sheets = [
  { name: "合並詳情", html: sheet_1 },
  { name: "發票詳情", html: sheet_2 }
];
tablesToExcel(sheets, "導出的excel"); */
function getTable(head, list, tableInfo) {
  //獲取完整表格
  let content = "";
  content += getH(head);
  content += "<tbody>";
  list.forEach((item) => {
    content += getB(item, tableInfo);
  });
  content += "</tbody>";
  return content;
  // let ele = document.createElement("table");
  // ele.innerHTML = content;
  // return ele;
}

function getH(list) {
  //拼接表頭
  let strH = "<thead><tr>";
  for (var item of list) {
    strH += `<th>${item}</th>`;
  }
  strH += "</tr></thead>";
  return strH;
}

/* 
  用寫html的方法導出excel時,excel會自動把一些格式轉換一下,有時達不預期的效果,此時可以通過樣式進行調整
  mso-number-format:@   文本
  mso-number-format:"0.000"   數字 
  mso-number-format:"mm/dd/yy"    日期 
  mso-number-format:"d\-mmm\-yyyy"   日期
  mso-number-format:Percent   百分比
*/

function getB(list, tableInfo) {
  console.log("list, tableInfo", list, tableInfo);
  //拼接表體
  let strB = "<tr>";
  list.forEach((item, index) => {
    let format = tableInfo[index].format;
    let style = tableInfo[index].style;
    var styleStr = "";
    if (typeof style == "function") {
      let styleFn = style(item, tableInfo);
      style = styleFn;
    }
    if (style instanceof Object) {
      for (var eleKey in style) {
        styleStr += `${eleKey}:${style[eleKey]};`;
      }
    } else {
      style = "";
    }
    if (typeof format == "string") {
      strB += `<td style="mso-number-format:'${format}';${styleStr}">${item}</td>`;
    } else if (typeof format == "function") {
      strB += `<td style="mso-number-format:'${format(
        item,
        tableInfo
      )}';${styleStr}">${item}</td>`;
    } else {
      // eslint-disable-next-line no-useless-escape
      strB += `<td style="mso-number-format:'\@';${styleStr}">${item}</td>`;
    }
  });
  strB += "</tr>";
  return strB;
}

const exportToExcel = function (excelInfo) {
  let excelName = excelInfo.name || "Workbook";
  let sheetList = excelInfo.sheets;
  if (sheetList && sheetList instanceof Array) {
    sheetList.forEach((item) => {
      let content = item.content;
      if (content.nodeType) {
        item.html = content.innerHTML;
      } else if (content instanceof Array) {
        let t_c = [],
          t_e = [];
        for (var H of item.tHeader) {
          t_e.push(H.key);
          t_c.push(H.name || "");
        }
        let data = formatJson(t_e, item.content);
        item.html = getTable(t_c, data, item.tHeader);
      } else if (typeof content == "string") {
        item.html = content;
      }
    });
    tablesToExcel(sheetList, excelName);
  } else {
    console.error("sheets為必傳屬性");
  }
};
const formatJson = (filterVal, jsonData) => {
  return jsonData.map((v) => filterVal.map((j) => v[j] || ""));
};

/* 
// 單元格內換行:<br style='mso-data-placement:same-cell;'/>
style:單元格樣式,支持函數、對象
format:單元格格式,支持函數、對象
content:當為數組是需要和tHeader搭配使用,當為字符串時表示導出的表格元素
const tHeader = [
            { key: "tbbm", name: "填報部門" },
            {
              key: "ypsj",
              name: "研判時間",
              style:'',
              format:'',
            },
            { key: "yxq", name: "有效期" },
            { key: "dtfxsj", name: "動態風險事件" },
            { key: "sjly", name: "事件來源" },
            { key: "jhlb", name: "計划類別" },
            {
              key: "jczdnr",
              name: "檢查重點內容",
            },
          ];
          let excelInfo = {
            name: "動態風險事件上報",
            sheets: [
              {
                name: "動態風險事件上報sheet1",
                content: list,
                tHeader: tHeader,
              },
              {
                name: "動態風險事件上報sheet2",
                content: list,
                tHeader: tHeader,
              },
            ],
          };
          importToExcel(excelInfo)
*/

  


免責聲明!

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



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