繁体   English   中英

DataTables - 导出数据中的所有列,无论表中可见什么

[英]DataTables - Export all columns in data, regardless of what's visible in the table

使用数据表 jquery 插件,在 ajax 调用成功后,我已经填充了(实际上是创建)的表。 这是示例代码,其中d是带有数据的 js 变量:

if ( ! $.fn.DataTable.isDataTable( '#DataTables_Table_0' ) ) {
    $('#DataTables_Table_0').DataTable ({
        "data" : d,
        "dom": "Blfrtip",
        "searching": false,
        "order": [],
        "paging": false,
        "columns" : [
            { "data" : "country" },
            { "data" : "round" },
            { "data" : "sector" },
            { "data" : "size" },
        ],
        "columnDefs": [{
            render: $.fn.dataTable.render.number(',', '.', 2)
        }],
        "buttons": [
            {
              extend: 'excelHtml5',
              text: 'Excel',
              customize: function( xlsx ) {
                setSheetName(xlsx, 'Data');
                addSheet(xlsx, '#DataTables_Table_1', 'Meta Data', 'Meta', '2');
              }

            },
            "csv"
        ]
    });
} else {
    $('#DataTables_Table_0').dataTable().fnClearTable();
    $('#DataTables_Table_0').dataTable().fnDestroy();

    let tu = last_column_name;

    $('#DataTables_Table_0').DataTable ({
        "destroy": true,
        "searching": false,
        "order": [],
        "paging": false,
        "data" : current_table_data,
        "dom": "Bfrtip",
        "columns" : [
            { "data" : "country" },
            { "data" : "round" },
            { "data" : "sector" },
            { "data" : tu},
        ],
        "buttons": [
            {
              extend: 'excelHtml5',
              text: 'Excel',
              customize: function( xlsx ) {
                setSheetName(xlsx, 'Data');
                addSheet(xlsx, '#DataTables_Table_1', 'Meta Data', 'Meta', '2');
              }

            },
            "csv"
        ]
    });

除此之外,我还使用按钮将我的数据导出到 Excel 和 CSV。 我认为一切正常,唯一的问题是它只导出表中可见或实际定义的列。

我想要做的是实际导出我与数据对象一起传递的所有列,而不仅仅是表中显示的列。 此外,直到一段时间前,这仍然有效,直到我更改了代码。 问题是我改变了很多,并没有真正测试导出那么多,当我这样做时,并没有真正考虑导出文档中的列。

如果它改变了任何东西,这里有更多的代码,自定义中使用的函数:

function getHeaderNames(table) {
      // Gets header names.
      //params:
      //  table: table ID.
      //Returns:
      //  Array of column header names.

      var header = $(table).DataTable().columns().header().toArray();

      var names = [];
      header.forEach(function(th) {
       names.push($(th).html());
      });

      return names;
    }

    function buildCols(data) {
      // Builds cols XML.
      //To do: deifne widths for each column.
      //Params:
      //  data: row data.
      //Returns:
      //  String of XML formatted column widths.

      var cols = '<cols>';

      for ( var i=0; i<data.length; i++) {
        var colNum = i + 1;
        cols += '<col min="' + colNum + '" max="' + colNum + '" width="20" customWidth="1"/>';
      }

      cols += '</cols>';

      return cols;
    }

    function buildRow(data, rowNum, styleNum) {
      // Builds row XML.
      //Params:
      //  data: Row data.
      //  rowNum: Excel row number.
      //  styleNum: style number or empty string for no style.
      //Returns:
      //  String of XML formatted row.

      var style = styleNum ? ' s="' + styleNum + '"' : '';

      var row = '<row r="' + rowNum + '">';
        if( rowNum > 2 ) {
            data.shift();
        }


      for (var i=0; i<data.length; i++) {
        var colNum = (i + 10).toString(36).toUpperCase();  // Convert to alpha

        var cr = colNum + rowNum;

        row += '<c t="inlineStr" r="' + cr + '"' + style + '>' +
                '<is>' +
                  '<t>' + data[i] + '</t>' +
                '</is>' +
              '</c>';
      }

      row += '</row>';

      return row;
    }

    function getTableData(table, title) {
      // Processes Datatable row data to build sheet.
      //Params:
      //  table: table ID.
      //  title: Title displayed at top of SS or empty str for no title.
      //Returns:
      //  String of XML formatted worksheet.

      var header = getHeaderNames(table);
      var table = $(table).DataTable();
      var rowNum = 1;
      var mergeCells = '';
      var ws = '';

      ws += buildCols(header);
      ws += '<sheetData>';

      if (title.length > 0) {
        ws += buildRow([title], rowNum, 51);
        rowNum++;

        var mergeCol = ((header.length - 1) + 10).toString(36).toUpperCase();

        mergeCells = '<mergeCells count="1">'+
          '<mergeCell ref="A1:' + mergeCol + '1"/>' +
                     '</mergeCells>';
      }

      ws += buildRow(header, rowNum, 2);
      rowNum++;

      // Loop through each row to append to sheet.    
      table.rows().every( function ( rowIdx, tableLoop, rowLoop ) {
        let secondtabledata = $('#DataTables_Table_1').DataTable();
        var data = secondtabledata.data();

        var tmp_arr = [];

        $.each( data, function(k, v) {
            tmp_arr.push( Object.values(v) );
        });

        // If data is object based then it needs to be converted 
        // to an array before sending to buildRow()
        ws += buildRow(tmp_arr[rowNum-3], rowNum, '');

        rowNum++;
      } );

      ws += '</sheetData>' + mergeCells;

      return ws;

    }

    function setSheetName(xlsx, name) {
      // Changes tab title for sheet.
      //Params:
      //  xlsx: xlxs worksheet object.
      //  name: name for sheet.

      if (name.length > 0) {
        var source = xlsx.xl['workbook.xml'].getElementsByTagName('sheet')[0];
        source.setAttribute('name', name);
      }
    }

    function addSheet(xlsx, table, title, name, sheetId) {
      //Clones sheet from Sheet1 to build new sheet.
      //Params:
      //  xlsx: xlsx object.
      //  table: table ID.
      //  title: Title for top row or blank if no title.
      //  name: Name of new sheet.
      //  sheetId: string containing sheetId for new sheet.
      //Returns:
      //  Updated sheet object.

      //Add sheet2 to [Content_Types].xml => <Types>
      //============================================
      var source = xlsx['[Content_Types].xml'].getElementsByTagName('Override')[1];
      var clone = source.cloneNode(true);
      clone.setAttribute('PartName','/xl/worksheets/sheet2.xml');
      xlsx['[Content_Types].xml'].getElementsByTagName('Types')[0].appendChild(clone);

      //Add sheet relationship to xl/_rels/workbook.xml.rels => Relationships
      //=====================================================================
      var source = xlsx.xl._rels['workbook.xml.rels'].getElementsByTagName('Relationship')[0];
      var clone = source.cloneNode(true);
      clone.setAttribute('Id','rId3');
      clone.setAttribute('Target','worksheets/sheet2.xml');
      xlsx.xl._rels['workbook.xml.rels'].getElementsByTagName('Relationships')[0].appendChild(clone);

      //Add second sheet to xl/workbook.xml => <workbook><sheets>
      //=========================================================
      var source = xlsx.xl['workbook.xml'].getElementsByTagName('sheet')[0];
      var clone = source.cloneNode(true);
      clone.setAttribute('name', name);
      clone.setAttribute('sheetId', sheetId);
      clone.setAttribute('r:id','rId3');
      xlsx.xl['workbook.xml'].getElementsByTagName('sheets')[0].appendChild(clone);

      //Add sheet2.xml to xl/worksheets
      //===============================
      var newSheet = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+
        '<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" mc:Ignorable="x14ac">'+
        getTableData(table, title) +

        '</worksheet>';

      xlsx.xl.worksheets['sheet2.xml'] = $.parseXML(newSheet);

    }

我真的找不到答案。 这个用例的可行解决方案是实际添加数据对象中存在的所有列,然后隐藏那些我不想显示的列。 这样,它也导出了不可见的列。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM