簡體   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