将多个html表导出到Excel

时间:2014-11-13 13:23:27

标签: html asp.net excel asp.net-mvc-4

我已经在互联网上搜索了答案,虽然我找到了一些,但他们大部分都是不完整或不工作。

我想要做的是:我有一个信息页面,显示有关客户或服务器的信息(或其他内容),这些信息显示在一个表格中,有时还有多个表格(我有时创建自己的表格)一些数据的表,并使用Html.Grid(Model.list)为列表中存储的其余数据创建表,所有这些都在1页上。

我发现这个网站很棒:http://www.excelmashup.com/并完全符合我对 1 表的要求,尽管我需要多个表格(它们必须都在同一个Excel中)文件)。我知道我可以创建多个文件(每个表1个),但这不是所需的输出。

所以我一直在搜索,我在stackoverflow上找到了一篇帖子:Export multiple HTML tables to Excel with JavaScript function

这似乎很有希望,所以我尝试使用它,但代码有一些小错误,我试图修复:

var tableToExcel = (function () {
    var uri = 'data:application/vnd.ms-excel;base64,'
        , 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>'
        , 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 (table, name) {
        if (!table.nodeType) table = document.getElementById(table)
        var ctx = { worksheet: name || 'Worksheet', table: table.innerHTML }
        window.location.href = uri + base64(format(template, ctx))
    }
})()

我用来触发它的按钮:

<input type="button" onclick="tableToExcel('InformatieTable', 'W3C Example Table')" value="Export to Excel">

但唉无济于事(我不知道如何处理if (!table.nodeType) table = table行,所以我只是评论它,因为它似乎没什么特别的。)

现在我收到一个错误,或者实际上并不是一个错误,但这是我在尝试运行此代码时所说的内容:

  

资源被解释为文档但是使用MIME类型application / vnd.ms-excel传输:&#34;数据:application / vnd.ms-excel; base64,PGh0bWwgeG1sbnM6bz0idXJuOnNjaGVtYXMtbW ... JzZXQ9VVRGLTgiLz48L2hlYWQ + PGJvZHk + PHRhYmxlPjwvdGFibGU + PC9ib2R5PjwvaHRtbD4 =&#34;

我在浏览器中下载了一个Excel文件,但是当我尝试打开它时,我收到一个关于内容和文件扩展名不匹配的错误,如果我还想打开它。因此,如果我单击“确定”,则会打开一个空的Excel工作表,然后就可以了。

我目前正在尝试修复该错误,但我认为它不会对Excel文件的内容产生任何影响。

有没有人可以帮我解决这个问题?或者提供另一种方法吗?

我更喜欢它运行客户端(所以jQuery / java)而不是服务器端来最小化服务器负载。

修改

我在http://www.codeproject.com/Tips/755203/Export-HTML-table-to-Excel-With-CSS找到了一个更好的jQuery示例(一个可行的) 这会将1个表转换为excel文件,这显然不够好。但是现在我有了这样做的代码,所以我应该能够通过网页上的所有表来调整它。

此外,还将此示例中的代码更新为正确使用的版本。 当我在尝试打开Excel文件时单击确定时它仍然会得到相同的错误它确实显示了表格的内容,所以我现在暂时忽略它。任何有此解决方案的人请分享。

2 个答案:

答案 0 :(得分:1)

感谢@Axel Richter我得到了答案,他向我提到了以下question

我已经对代码进行了一些修改,因此它会占用网页上的所有表格,所以它现在看起来像这样:

<script type="text/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 (wsnames, wbname, appname) {
            var ctx = "";
            var workbookXML = "";
            var worksheetsXML = "";
            var rowsXML = "";
            var tables = $('table');
            for (var i = 0; i < tables.length; 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.replace('<br>', '')
                               , 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);

            console.log(workbookXML);

            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);
        }
    })();
</script>

所以现在,当我想要一个页面有一个选项导出到excel时,我添加了一个对该脚本的参考,我将以下按钮添加到我的页面:

<button onclick="tablesToExcel(['ServerInformatie', 'Relaties'], 'VirtueleMachineInfo.xls', 'Excel')">Export to Excel</button>

所以方法:

tablesToExcel(WorksheetNames, fileName, 'Excel')

其中worksheetNames是一个数组,需要包含与页面上的表一样多的名称(或更多)。您可以选择以不同的方式创建工作表名称。 并且fileName是当前正在下载的文件的名称。

在1个工作表中没有全部内容是一种耻辱,但至少现在这样做了。

答案 1 :(得分:-1)

这是我用来将多个 HTML 表格放在同一个 Excel 工作表中的代码:

import TableExport from 'tableexport';

const tbOptions = {
  formats: ["xlsx"],    // (String[]), filetype(s) for the export, (default: ['xlsx', 'csv', 'txt'])
  bootstrap: true,                   // (Boolean), style buttons using bootstrap, (default: true)
  exportButtons: false,                // (Boolean), automatically generate the built-in export buttons for each of the specified formats (default: true)
  position: "bottom",                 // (top, bottom), position of the caption element relative to table, (default: 'bottom')
}

DowlandExcel = (key) => {
  const table = TableExport(document.getElementById(key), tbOptions);
  var exportData = table.getExportData();
  var xlsxData = exportData[key].xlsx;
  console.log(xlsxData); // Replace with the kind of file you want from the exportData
  table.export2file(xlsxData.data, xlsxData.mimeType, xlsxData.filename, xlsxData.fileExtension, xlsxData.merges, xlsxData.RTL, xlsxData.sheetname)
}

DowlandExcelMultiTable = (keys) => {

  const tables = []
  const xlsxDatas = []
  keys.forEach(key => {
    const selector = document.getElementById(key);
    if (selector) {
      const table = TableExport(selector, tbOptions);
      tables.push(table);
      xlsxDatas.push(table.getExportData()[key].xlsx)
    }
  });

  const mergeXlsxData = {
    RTL: false,
    data: [],
    fileExtension: ".xlsx",
    filename: 'rapor',
    merges: [],
    mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    sheetname: "Rapor"
  }
  for (let i = 0; i < xlsxDatas.length; i++) {
    const xlsxData = xlsxDatas[i];
    mergeXlsxData.data.push(...xlsxData.data)

    xlsxData.merges = xlsxData.merges.map(merge => {
      const diff = mergeXlsxData.data.length - xlsxData.data.length;

      merge.e.r += diff;
      merge.s.r += diff;

      return merge
    });
    mergeXlsxData.merges.push(...xlsxData.merges)
    mergeXlsxData.data.push([null]);
  }
  console.log(mergeXlsxData);
  tables[0].export2file(mergeXlsxData.data, mergeXlsxData.mimeType, mergeXlsxData.filename, mergeXlsxData.fileExtension, mergeXlsxData.merges, mergeXlsxData.RTL, mergeXlsxData.sheetname)
}