如何将 html 表格转换为具有多个工作表的 excel?

IT技术 javascript jquery json html
2021-02-15 13:05:49

如何将多个 html 表转换为包含多个工作表的 Excel 表?你能帮忙解决这个问题吗?

我的例子https://jsfiddle.net/kdkd/5p22gdag/

        function tablesToExcel() {
        {

            var tab_text = "<table border='2px'><tr bgcolor='#87AFC6'>";
            var textRange; var j = 0;
            tab = document.getElementById('tbl2'); // id of table


            for (j = 0 ; j < tab.rows.length ; j++) {
                tab_text = tab_text + tab.rows[j].innerHTML + "</tr>";
                //tab_text=tab_text+"</tr>";
            }

            tab_text = tab_text + "</table>";
            var ua = window.navigator.userAgent;
            var msie = ua.indexOf("MSIE ");

            if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./))      // If Internet Explorer
            {
                txtArea1.document.open("txt/html", "replace");
                txtArea1.document.write(tab_text);
                txtArea1.document.close();
                txtArea1.focus();
                sa = txtArea1.document.execCommand("SaveAs", true, "Say Thanks to Sumit.xls");
            }
            else                 //other browser not tested on IE 11
                sa = window.open('data:application/vnd.ms-excel,' + encodeURIComponent(tab_text));


            return (sa);
        }

 }
6个回答

您可以执行以下操作:这是完整示例

网址

<table id="tbl1" class="table2excel">
        <tr>
            <td>Product</td>
            <td>Price</td>
            <td>Available</td>
            <td>Count</td>
        </tr>
        <tr>
            <td>Bred</td>
            <td>1</td>
            <td>2</td>
             <td>3</td>
        </tr>
        <tr>
            <td>Butter</td>
            <td>4   </td>
            <td>5   </td>
            <td >6  </td>
        </tr>
  </table>
<hr>

  <table id="tbl2" class="table2excel">
        <tr>
            <td>Product</td>
            <td>Price</td>
            <td>Available</td>
            <td>Count</td>
        </tr>
        <tr>
            <td>Bred</td>
            <td>7</td>
            <td>8</td>
            <td>9</td>
        </tr>
        <tr>
            <td>Butter</td>
            <td>14</td>
            <td>15</td>
            <td >16</td>
        </tr>
    </table>


<button  onclick="tablesToExcel(['tbl1','tbl2'], ['ProductDay1','ProductDay2'], 'TestBook.xls', 'Excel')">Export to Excel</button>

Javascript:

 var tablesToExcel = (function() {
    var uri = 'data:application/vnd.ms-excel;base64,'
    , tmplWorkbookXML = '<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?><Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">'
      + '<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Author>Axel Richter</Author><Created>{created}</Created></DocumentProperties>'
      + '<Styles>'
      + '<Style ss:ID="Currency"><NumberFormat ss:Format="Currency"></NumberFormat></Style>'
      + '<Style ss:ID="Date"><NumberFormat ss:Format="Medium Date"></NumberFormat></Style>'
      + '</Styles>' 
      + '{worksheets}</Workbook>'
    , tmplWorksheetXML = '<Worksheet ss:Name="{nameWS}"><Table>{rows}</Table></Worksheet>'
    , tmplCellXML = '<Cell{attributeStyleID}{attributeFormula}><Data ss:Type="{nameType}">{data}</Data></Cell>'
    , 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, wsnames, wbname, appname) {
      var ctx = "";
      var workbookXML = "";
      var worksheetsXML = "";
      var rowsXML = "";

      for (var i = 0; i < tables.length; i++) {
        if (!tables[i].nodeType) tables[i] = document.getElementById(tables[i]);
        for (var j = 0; j < tables[i].rows.length; j++) {
          rowsXML += '<Row>'
          for (var k = 0; k < tables[i].rows[j].cells.length; k++) {
            var dataType = tables[i].rows[j].cells[k].getAttribute("data-type");
            var dataStyle = tables[i].rows[j].cells[k].getAttribute("data-style");
            var dataValue = tables[i].rows[j].cells[k].getAttribute("data-value");
            dataValue = (dataValue)?dataValue:tables[i].rows[j].cells[k].innerHTML;
            var dataFormula = tables[i].rows[j].cells[k].getAttribute("data-formula");
            dataFormula = (dataFormula)?dataFormula:(appname=='Calc' && dataType=='DateTime')?dataValue:null;
            ctx = {  attributeStyleID: (dataStyle=='Currency' || dataStyle=='Date')?' ss:StyleID="'+dataStyle+'"':''
                   , nameType: (dataType=='Number' || dataType=='DateTime' || dataType=='Boolean' || dataType=='Error')?dataType:'String'
                   , data: (dataFormula)?'':dataValue
                   , attributeFormula: (dataFormula)?' ss:Formula="'+dataFormula+'"':''
                  };
            rowsXML += format(tmplCellXML, ctx);
          }
          rowsXML += '</Row>'
        }
        ctx = {rows: rowsXML, nameWS: wsnames[i] || 'Sheet' + i};
        worksheetsXML += format(tmplWorksheetXML, ctx);
        rowsXML = "";
      }

      ctx = {created: (new Date()).getTime(), worksheets: worksheetsXML};
      workbookXML = format(tmplWorkbookXML, ctx);



      var link = document.createElement("A");
      link.href = uri + base64(workbookXML);
      link.download = wbname || 'Workbook.xls';
      link.target = '_blank';
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    }
  })();
此链接可能对您有所帮助。stackoverflow.com/questions/18467418/...
2021-04-17 13:05:49
这是纯粹的天才!:-)
2021-04-27 13:05:49
我试过这个,但我的表有内联 CSS,所以它不工作。请检查这个小提琴jsfiddle.net/kdkd/qxLn3h86/49
2021-04-30 13:05:49
这个答案在 IE 11 中不起作用。有没有其他解决方案可以让它在 IE 上工作?提前致谢
2021-05-04 13:05:49
那是文件,但两个代码都不同,一个用于创建多个工作表,另一个用于使用 CSS .. 我如何合并???
2021-05-15 13:05:49

是一个更好的解决方案,它支持以最新的 Excel 格式(即 xlsx )导出表格。如果 Chrome 上导出的总行数超过 3407,则已接受的解决方案将失败。

上面链接的一个例子:http : //jsfiddle.net/6ckj281f/

html

<button onclick="saveFile()">Save XLSX file</button>

javascript

window.saveFile = function saveFile () {
var data1 = [{a:1,b:10},{a:2,b:20}];
var data2 = [{a:100,b:10},{a:200,b:20}];
var opts = [{sheetid:'One',header:true},{sheetid:'Two',header:false}];
var res = alasql('SELECT INTO XLSX("restest344b.xlsx",?) FROM ?',
                 [opts,[data1,data2]]);
}
哦,这正是我要找的。谢谢!
2021-04-20 13:05:49

没有在互联网上找到任何东西来解决这个问题,所以我创建了自己的。这是一个创建 2 个或更多工作表(每张表 1 个工作表)并且正常工作的工作示例。享受!:)

运行 https://jsfiddle.net/xvkt0yw9/ 中的示例

这是XLS 导出(网页.mht表示的~ 逆向工程工作表名称在每个表data-SheetName属性中定义该函数可以很容易地转换为其他编程语言。(基本上全是replace me s)

还为单元格编号格式提供了内联样式(作为文本,常规,2 位小数)

注意:无论您是否设置选项,单元格网格都会显示... 警告不要缩进 javascript 函数。(我不知道如果你这样做了 XLS 会发生什么,没有测试,没有) Html: (将以下内容放在test.html文件中并在浏览器中运行。单击按钮并打开导出的 Worksheet.xls)

<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<script type="text/javascript">
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"/>`
    , template_HTMLWorksheet = `
------=_NextPart_dummy
Content-Location: sheet{SheetIndex}.htm
Content-Type: text/html; charset=windows-1252

` + html_start + `
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
    <link id="Main-File" rel="Main-File" href="../WorkBook.htm">
    <link rel="File-List" href="filelist.xml">
</head>
<body><table>{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=windows-1252

` + html_start + `
<head>
<meta name="Excel Workbook Frameset">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<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: ''
        };
        var tables = jQuery(tables);
        $.each(tables,function(SheetIndex){
            var $table = $(this);
            var SheetName = $table.attr('data-SheetName');
            if($.trim(SheetName) === ''){
                SheetName = 'Sheet' + SheetIndex;
            }
            context_WorkBook.ExcelWorksheets += format(template_ExcelWorksheet, {
                SheetIndex: SheetIndex
            ,   SheetName: SheetName
            });
            context_WorkBook.HTMLWorksheets += format(template_HTMLWorksheet, {
                SheetIndex: SheetIndex
            ,   SheetContent: $table.html()
            });
            context_WorkBook.ListWorksheets += format(template_ListWorksheet, {
                SheetIndex: SheetIndex
            });
        });

        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);
    }
})(jQuery);
</script>
</head>
<body>
    <button onclick="tablesToExcel('#table_1,#table_2', 'WorkSheet.xls');">HTML Tables to XLS sheets</button>
    <table id="table_1" data-SheetName="My custom sheet 1">
        <thead>
            <tr >
                <td colspan="4" style="border-color:#fff;">
                    Left info
                </td>
                <td colspan="3" class="text-right" style="border-color:#fff;">
                    Right info
                </td>
            </tr>
            <tr>
                <th colspan="7" style="border-color:#fff;text-decoration:underline;font-size:2em;" class="text-center">
                    Title
                </th>
            </tr>
            <tr>
                <th colspan="7" style="border-left-color:#fff; border-right-color:#fff;border-top-color:#fff;text-decoration:underline;font-size:1.5em;" class="text-center">
                    Subtitle
                </th>
            </tr>
            <tr>
                <th colspan="7" style="border-left-color:#fff;border-right-color:#fff;border-top-color:#fff;height:50px;">
                    Spacer
                </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td style="mso-number-format:'\@'">1</td>
                <td style="mso-number-format:'General'">2</td>
                <td style="mso-number-format:'0\.00'">3</td>
                <td>info</td>
                <td>info</td>
                <td>info</td>
                <td>info</td>
            </tr>
        </tbody>
    </table>
    <table id="table_2" data-SheetName="My custom worksheet 2">
        <thead>
            <tr >
                <td colspan="2" style="border-color:#fff;">
                    Left info 2
                </td>
                <td colspan="2" class="text-right" style="border-color:#fff;">
                    Right info 2
                </td>
            </tr>
            <tr>
                <th colspan="4" style="border-color:#fff;text-decoration:underline;font-size:2em;" class="text-center">
                    Title 2
                </th>
            </tr>
            <tr>
                <th colspan="4" style="border-left-color:#fff; border-right-color:#fff;border-top-color:#fff;text-decoration:underline;font-size:1.5em;" class="text-center">
                    Subtitle 2
                </th>
            </tr>
            <tr>
                <th colspan="4" style="border-left-color:#fff;border-right-color:#fff;border-top-color:#fff;height:50px;">
                    Spacer 2
                </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td style="mso-number-format:'\@'">3</td>
                <td style="mso-number-format:'General'">4</td>
                <td style="mso-number-format:'0\.00'">5</td>
                <td>info2</td>
                <td>info3</td>
                <td>info4</td>
                <td>info5</td>
            </tr>
        </tbody>
    </table>
</body>
</html>

Bhutani Vijay 的代码运行良好。对于 IE 11 兼容性,我使用了 Blob 对象,如下所示:

var tablesToExcel = (function() {
  var uri = 'data:application/vnd.ms-excel;base64,',
    tmplWorkbookXML = '<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?><Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">' +
    '<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Author>Axel Richter</Author><Created>{created}</Created></DocumentProperties>' +
    '<Styles>' +
    '<Style ss:ID="Currency"><NumberFormat ss:Format="Currency"></NumberFormat></Style>' +
    '<Style ss:ID="Date"><NumberFormat ss:Format="Medium Date"></NumberFormat></Style>' +
    '</Styles>' +
    '{worksheets}</Workbook>',
    tmplWorksheetXML = '<Worksheet ss:Name="{nameWS}"><Table>{rows}</Table></Worksheet>',
    tmplCellXML = '<Cell{attributeStyleID}{attributeFormula}><Data ss:Type="{nameType}">{data}</Data></Cell>',
    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, wsnames, wbname, appname) {
    var ctx = "";
    var workbookXML = "";
    var worksheetsXML = "";
    var rowsXML = "";

    for (var i = 0; i < tables.length; i++) {
      if (!tables[i].nodeType) tables[i] = document.getElementById(tables[i]);
      for (var j = 0; j < tables[i].rows.length; j++) {
        rowsXML += '<Row>'
        for (var k = 0; k < tables[i].rows[j].cells.length; k++) {
          var dataType = tables[i].rows[j].cells[k].getAttribute("data-type");
          var dataStyle = tables[i].rows[j].cells[k].getAttribute("data-style");
          var dataValue = tables[i].rows[j].cells[k].getAttribute("data-value");
          dataValue = (dataValue) ? dataValue : tables[i].rows[j].cells[k].innerHTML;
          var dataFormula = tables[i].rows[j].cells[k].getAttribute("data-formula");
          dataFormula = (dataFormula) ? dataFormula : (appname == 'Calc' && dataType == 'DateTime') ? dataValue : null;
          ctx = {
            attributeStyleID: (dataStyle == 'Currency' || dataStyle == 'Date') ? ' ss:StyleID="' + dataStyle + '"' : '',
            nameType: (dataType == 'Number' || dataType == 'DateTime' || dataType == 'Boolean' || dataType == 'Error') ? dataType : 'String',
            data: (dataFormula) ? '' : dataValue,
            attributeFormula: (dataFormula) ? ' ss:Formula="' + dataFormula + '"' : ''
          };
          rowsXML += format(tmplCellXML, ctx);
        }
        rowsXML += '</Row>'
      }
      ctx = {
        rows: rowsXML,
        nameWS: wsnames[i] || 'Sheet' + i
      };
      worksheetsXML += format(tmplWorksheetXML, ctx);
      rowsXML = "";
    }

    ctx = {
      created: (new Date()).getTime(),
      worksheets: worksheetsXML
    };
    workbookXML = format(tmplWorkbookXML, ctx);

    var link = document.createElement("A");
    
    // IE 11
    if (window.navigator.msSaveBlob) {
      var blob = new Blob([workbookXML], {
        type: "application/csv;charset=utf-8;"
      });
      navigator.msSaveBlob(blob, 'test.xls');
    }
    // Chrome and other browsers
    else {
      link.href = uri + base64(workbookXML);
    }

    link.download = wbname || 'Workbook.xls';
    link.target = '_blank';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  }
})();

对多张纸使用下面的代码。我正在使用三个表数据来生成 excel。导入库:

从“xlsx”导入 * 作为 XLSX;

static doExcel1(tableId1, tableId2, tableId3) {

    let targetTableElm1 = document.getElementById(tableId1);
    let targetTableElm2 = document.getElementById(tableId2);
    let targetTableElm3 = document.getElementById(tableId3);

    const wb = { SheetNames: [], Sheets: {} };
    var ws1 = XLSX.utils.table_to_book(targetTableElm1).Sheets.Sheet1;
    wb.SheetNames.push("Sheet1"); wb.Sheets["Sheet1"] = ws1;

    var ws2 = XLSX.utils.table_to_book(targetTableElm2).Sheets.Sheet1;
    wb.SheetNames.push("Sheet2"); wb.Sheets["Sheet2"] = ws2;

    var ws3 = XLSX.utils.table_to_book(targetTableElm3).Sheets.Sheet1;
    wb.SheetNames.push("Sheet3"); wb.Sheets["Sheet3"] = ws3;
    console.log(ws1); console.log(ws2); console.log(ws3); console.log(wb);
    const blob = new Blob([this.s2ab(XLSX.write(wb, { bookType: 'xlsx', type: 'binary' }))], {
      type: "application/octet-stream"
    });
    const link = document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    link.download = 'demo.xlsx';

    document.body.appendChild(link);

    link.click();

    document.body.removeChild(link);
  }
  static s2ab(s) {
    const buf = new ArrayBuffer(s.length);
    const view = new Uint8Array(buf);
    for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
    return buf;
  }

使用表 ID 调用: doExcel1("ExampleTable1","ExampleTable2","ExampleTable3"); 单击按钮。

注意:以上解决方案仅适用于 angular,如果您想在 node 或 js 中使用它,则需要进行一些更改。