使用JavaScript / JQuery将HTML表格数据导出到Excel在Chrome浏览器中无法正常工作

126
我有一个 HTML 表格在 velocity 模板中。我想使用 JavaScript 或 jQuery 将 html 表格数据导出到 Excel,兼容所有浏览器。 我正在使用以下脚本。
<script type="text/javascript">
function ExportToExcel(mytblId){
       var htmltable= document.getElementById('my-table-id');
       var html = htmltable.outerHTML;
       window.open('data:application/vnd.ms-excel,' + encodeURIComponent(html));
    }
</script>

这段脚本在 Mozilla Firefox 中运行良好,它会弹出一个Excel对话框并询问打开或保存选项。但是当我在 Chrome浏览器 中测试相同的脚本时,它不像预期的那样工作,单击按钮时没有弹出Excel。数据以“文件类型:文件”的形式下载到文件中,没有扩展名,如.xls。 Chrome控制台中没有错误。
Jsfiddle示例:

http://jsfiddle.net/insin/cmewv/

这在Mozilla中运行良好,但在Chrome中不行。
Chrome浏览器测试用例:
第一张图片:我点击“导出到Excel”按钮。

First Image:I click on Export to excel button

"结果为:"

Result


测试用例适用于Chrome。 - Sukane
1
如果您使用的是开源产品LibreOffice和Chrome浏览器,则上述测试用例将失败。但如果您安装了MS Office,则代码将正常工作。 - Sukane
16个回答

208
Excel导出脚本适用于IE7+、Firefox和Chrome浏览器。
function fnExcelReport() {
    var tab_text = "<table border='2px'><tr bgcolor='#87AFC6'>";
    var j = 0;
    var tab = document.getElementById('headerTable'); // 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>";
    tab_text = tab_text.replace(/<A[^>]*>|<\/A>/g, "");//remove if u want links in your table
    tab_text = tab_text.replace(/<img[^>]*>/gi, ""); // remove if u want images in your table
    tab_text = tab_text.replace(/<input[^>]*>|<\/input>/gi, ""); // reomves input params

    var msie = window.navigator.userAgent.indexOf("MSIE ");

    // If Internet Explorer
    if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) {
        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;
}

只需创建一个空白的iframe即可:
<iframe id="txtArea1" style="display:none"></iframe>

在以下情况下调用此函数:
<button id="btnExport" onclick="fnExcelReport();"> EXPORT </button>

4
在Chrome浏览器中,使用此方法单击下载按钮时,什么也不会发生。没有任何控制台错误或其他内容。 - Kyle Bachan
14
如何更改随机名称。我想设置特定名称。 - osman Rahimi
26
"download.xls的文件格式和扩展名不匹配",这让经理不太开心 :/ 你有什么想法吗? - Tom Stickel
2
能否将文件名从“download.xls”更改为其他名称? - Youssef Boudaya
2
导出的文件名始终为 download.xls - J M
显示剩余48条评论

46

6
哇!这是一个很棒的插件!而且它还嵌入了几个其他的插件!导出、排序、重排、打印预览等功能,一次解决了我所有数据显示的需求! - El Gucs
我可以使用这个插件为我的Excel应用样式吗? - Shruthi Sathyanarayana
@Addy 这只是一个 DataTables 的解决方案,对吧? - Karl
1
导出按钮将删除每个页面的行数下拉菜单,如果您想保留这两个东西?请查看https://datatables.net/extensions/buttons/examples/initialisation/pageLength.html以解决此问题。 - Kaushik Das
这个插件很棒。有没有一种方法可以仅提取相关代码以导出数据并在此处突出显示?那将是非常有帮助的。提前谢谢。 - Murtuza Husain
这很好!但我有一个问题,这个插件不支持<thead>中的多个<tr>,是否有解决方法,请告诉我。谢谢! - Mizanur Rahman

43

这可能会有所帮助

function exportToExcel(){
var htmls = "";
            var uri = 'data:application/vnd.ms-excel;base64,';
            var template = '<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"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>'; 
            var base64 = function(s) {
                return window.btoa(unescape(encodeURIComponent(s)))
            };

            var format = function(s, c) {
                return s.replace(/{(\w+)}/g, function(m, p) {
                    return c[p];
                })
            };

            htmls = "YOUR HTML AS TABLE"

            var ctx = {
                worksheet : 'Worksheet',
                table : htmls
            }


            var link = document.createElement("a");
            link.download = "export.xls";
            link.href = uri + base64(format(template, ctx));
            link.click();
}

2
如果我只想导出在HTML表格中可见的列,该怎么办? - Nouman Bhatti
嗨,我无法在表格中执行任何 EXCEL 操作,例如:自动求和。这是因为这个 EXCEL 表格的数据格式问题还是其他问题?我需要帮助执行一些操作。 - Nanda Kishore Allu

27

你可以使用 tableToExcel.js 将表格导出为 Excel 文件。

它的工作方式如下:

1). 将以下 CDN 包含在您的项目/文件中

<script src="https://cdn.jsdelivr.net/gh/linways/table-to-excel@v1.0.4/dist/tableToExcel.js"></script>

2). 使用JavaScript:

<button id="btnExport" onclick="exportReportToExcel(this)">EXPORT REPORT</button>

function exportReportToExcel() {
  let table = document.getElementsByTagName("table"); // you can use document.getElementById('tableId') as well by providing id to the table tag
  TableToExcel.convert(table[0], { // html code may contain multiple tables so here we are refering to 1st table tag
    name: `export.xlsx`, // fileName you could use any name
    sheet: {
      name: 'Sheet 1' // sheetName
    }
  });
}

3). 或者通过使用Jquery

<button id="btnExport">EXPORT REPORT</button>

$(document).ready(function(){
    $("#btnExport").click(function() {
        let table = document.getElementsByTagName("table");
        TableToExcel.convert(table[0], { // html code may contain multiple tables so here we are refering to 1st table tag
           name: `export.xlsx`, // fileName you could use any name
           sheet: {
              name: 'Sheet 1' // sheetName
           }
        });
    });
});
您可以参考此Github链接以获取其他信息: https://github.com/linways/table-to-excel/tree/master 或访问以下链接以查看实时示例: https://codepen.io/rohithb/pen/YdjVbb 希望这能帮助到某些人 :-)

1
这是最简单和最好的方法之一,感谢@aman。 - Jegan Baskaran
我们是否有办法在导出之前忽略一些列? - Jegan Baskaran
1
@JeganBaskaran 是的,这个库自带内置属性 "<tr data-exclude="true"></tr>"。我知道有点晚,但可能会对某些人有所帮助 :) - Ammar F-A

15

你可以使用具有 onclick 事件的链接来代替使用 window.open
同时,你还可以将html表格放入uri中并设置文件名以便下载。

实时演示:

function exportF(elem) {
  var table = document.getElementById("table");
  var html = table.outerHTML;
  var url = 'data:application/vnd.ms-excel,' + escape(html); // Set your html table into url 
  elem.setAttribute("href", url);
  elem.setAttribute("download", "export.xls"); // Choose the file name
  return false;
}
<table id="table" border="1">
  <tr>
    <td>
      Foo
    </td>
    <td>
      Bar
    </td>
  </tr>
</table>

<a id="downloadLink" onclick="exportF(this)">Export to excel</a>


1
我该如何在函数中设置表格边框、单元格宽度等? - Zeffry Reynando

14

TableExport是一个简单易用的库,能够将HTML表格导出为xlsx、xls、csv和txt文件。

要使用该库,只需调用TableExport构造函数即可:

new TableExport(document.getElementsByTagName("table"));

// OR simply

TableExport(document.getElementsByTagName("table"));

// OR using jQuery

$("table").tableExport(); 

可以传入其他属性来自定义表格、按钮和导出数据的外观。 在此处查看更多信息


它支持PhantomJs吗?如何报告错误? - golimar

9

Uchit,谢谢您的回答。但是我已经尝试过这个例子了。正如我所提到的,它可以在Mozilla浏览器中很好地工作,但不适用于Chorme。能否请您在Chrome浏览器中尝试此示例? - Sukane
5
我已在 jsfiddle 上尝试了您的代码并获得了积极的结果。它即使在 Chrome 中也可以正常工作。您可以在上面的图像中看到下载成功。 - Uchit Shrestha
1
Uchit,谢谢。是的,代码可以运行。问题在于我使用的是Libre Office,所以在Chrome中导出到Excel时不太好用(请参考我的问题中的屏幕截图)。但是在MS Office中它可以工作,正如你所提到的。感谢您提供了一个jQuery代码。 - Sukane
这个函数没有导出具有下拉框和时间戳的字段的值。 - SNT93
它不能处理多个HTML表格,只能处理一个表格。我该如何处理多个表格???? - Ignacio Chiazzo
我无法打开提到的链接? - Isma

7

使用Jquery的最简单方法

只需在head标签后添加以下内容:

<script src="https://cdn.jsdelivr.net/gh/linways/table-to-excel@v1.0.4/dist/tableToExcel.js"></script>

然后在Body标签内添加Jquery脚本:

<script type="text/javascript">
  $(document).ready(function () {
      $("#exportBtn1").click(function(){
        TableToExcel.convert(document.getElementById("tab1"), {
            name: "Traceability.xlsx",
            sheet: {
            name: "Sheet1"
            }
          });
        });
  });
</script>

然后添加HTML按钮:

<button id="exportBtn1">Export To Excel</button><br><br>

注意:"exportBtn1" 将是按钮 ID,而 "tab1" 将是表格 ID。

7
我的合并示例:

https://www.codexworld.com/export-html-table-data-to-excel-using-javascript https://bl.ocks.org/Flyer53/1de5a78de9c89850999c

(该文本为两个网址的链接,用于导出 HTML 表格数据到 Excel。)
function exportTableToExcel(tableId, filename) {
    let dataType = 'application/vnd.ms-excel';
    let extension = '.xls';

    let base64 = function(s) {
        return window.btoa(unescape(encodeURIComponent(s)))
    };

    let template = '<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"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>';
    let render = function(template, content) {
        return template.replace(/{(\w+)}/g, function(m, p) { return content[p]; });
    };

    let tableElement = document.getElementById(tableId);

    let tableExcel = render(template, {
        worksheet: filename,
        table: tableElement.innerHTML
    });

    filename = filename + extension;

    if (navigator.msSaveOrOpenBlob)
    {
        let blob = new Blob(
            [ '\ufeff', tableExcel ],
            { type: dataType }
        );

        navigator.msSaveOrOpenBlob(blob, filename);
    } else {
        let downloadLink = document.createElement("a");

        document.body.appendChild(downloadLink);

        downloadLink.href = 'data:' + dataType + ';base64,' + base64(tableExcel);

        downloadLink.download = filename;

        downloadLink.click();
    }
}

1
未捕获的引用错误:base64未定义。 - Pedro Joaquín

4

关于Jun 6 '14 at 11:59的sampopes答案:

我插入了一个字号为20px的CSS样式来显示更大的Excel数据。在sampopes的代码中,缺少前导的<tr>标签,所以我首先输出标题,然后在循环中输出其他表格行。

function fnExcelReport()
{
    var tab_text = '<table border="1px" style="font-size:20px" ">';
    var textRange; 
    var j = 0;
    var tab = document.getElementById('DataTableId'); // id of table
    var lines = tab.rows.length;

    // the first headline of the table
    if (lines > 0) {
        tab_text = tab_text + '<tr bgcolor="#DFDFDF">' + tab.rows[0].innerHTML + '</tr>';
    }

    // table data lines, loop starting from 1
    for (j = 1 ; j < lines; j++) {     
        tab_text = tab_text + "<tr>" + tab.rows[j].innerHTML + "</tr>";
    }

    tab_text = tab_text + "</table>";
    tab_text = tab_text.replace(/<A[^>]*>|<\/A>/g, "");             //remove if u want links in your table
    tab_text = tab_text.replace(/<img[^>]*>/gi,"");                 // remove if u want images in your table
    tab_text = tab_text.replace(/<input[^>]*>|<\/input>/gi, "");    // reomves input params
    // console.log(tab_text); // aktivate so see the result (press F12 in browser)

    var ua = window.navigator.userAgent;
    var msie = ua.indexOf("MSIE "); 

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

    return (sa);
}   

请问您如何从导出到Excel中删除特定列呢?例如,我想避免 tab.rows[j].cells[13],非常感谢您的帮助。 - Disera
非常好的答案,对于一个非常简单的表格,我只会保留最后一行:window.open('data:application/vnd.ms-excel,' + encodeURIComponent(tab_text)); 编码非常重要。 - pearpages

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接