草庐IT

关于asp.net:将多个html表格导出到Excel

codeneng 2023-03-28 原文

Export multiple html tables to Excel

我已经在互联网上寻找答案,虽然我找到了一些答案,但它们大多不完整或不起作用。

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

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

于是我继续搜索,在stackoverflow上找到了一个帖子:Export multiple HTML tables to Excel with JavaScript function

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

1
2
3
4
5
6
7
8
9
10
11
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))
    }
})()

我用来触发它的按钮:

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

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

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

Resource interpreted as Document but transferred with MIME type application/vnd.ms-excel:"data:application/vnd.ms-excel;base64,PGh0bWwgeG1sbnM6bz0idXJuOnNjaGVtYXMtbW…JzZXQ9VVRGLTgiLz48L2hlYWQ+PGJvZHk+PHRhYmxlPjwvdGFibGU+PC9ib2R5PjwvaHRtbD4=".

我在我的浏览器中下载了一个 Excel 文件,但是当我尝试打开它时,我收到一个关于内容和文件扩展名不匹配以及我是否仍想打开它的错误。所以如果我点击确定,它会打开一个空的 Excel 工作表,就是这样。

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

有没有人可以帮我解决这个问题?或者提供其他方式来执行此操作?

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

编辑

我在 http://www.codeproject.com/Tips/755203/Export-HTML-table-to-Excel-With-CSS 上找到了一个更好的 jQuery 示例(一个可以工作的)
这会将 1 个表格转换为 excel 文件,这显然不够好。但是现在我有代码来执行此操作,因此我应该能够对其进行调整以循环遍历网页上的所有表格。

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

  • 出于安全原因,您无法使用 Javascript 访问用户文件,因此您必须在服务器上执行此操作。但是,MIME 类型问题是一个很大的提示。如果我是你,我会先看看 IIS MIME 类型。
  • 我一直在努力寻找解决方案,找到了一些有希望的线索,但还没有具体的线索。
  • 请阅读:rackspace.com/knowledge_center/article/
  • 是的,我这样做了,但仍然没有帮助得到错误。
  • 真正的目标是什么?将多个 HTML 表格放入一张 Excel 表格中?或者将多个 HTML 表格放入一个 Excel 工作簿中的多个 Excel 工作表中?如果是后者,那么看看这个:stackoverflow.com/questions/26301811/ 你的"错误"并不是真正的错误,而是一个警告信息。有关此问题的讨论,请参见:stackoverflow.com/questions/26825585/。


感谢@Axel Richter,我得到了答案,他让我回答了以下问题

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<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('', '')
                               , 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);
        }
    })();

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

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

所以方法:

1
tablesToExcel(WorksheetNames, fileName, 'Excel')

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

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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)
}

  • 请注意 Stack Overflow 严格来说是一个英文 Q

有关关于asp.net:将多个html表格导出到Excel的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  3. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  4. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  5. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  6. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  7. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  8. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  9. ruby-on-rails - 使用 Sublime Text 3 突出显示 HTML 背景语法中的 ERB? - 2

    所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择

  10. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

随机推荐