从数据表中导出数据时,使用选择元素会导出选择元素中的每个选项。

6

我想给我的数据表格添加导出按钮,我的表格里包含了选择框,问题是 - 它会导出选择框中包括的所有选项值... 我使用ajax从服务器获取结果,然后使用dataSrc函数在渲染之前处理不同的数据:

dataTableInit: function (columns_def) {
    var me = this;
    me.dataTable_obj = $('#leads_table').DataTable({
       "pageLength": per_page,
        dom: 'Blfrtip',
        buttons: [
            'copy', 'csv', 'excel', 'pdf', 'print'
        ],
        "order": [order],
        "ajax": {
            url: route,
            type: method,
            data: filtering_data,
            "dataSrc": function (json) {
                return me.setLeadsTableData(json);
            }
        },
       "columns": columns_def,
       ....

setLeadsTableData函数中,我会检查从服务器返回的列,如果它是应该是下拉框的列,我会更改其模板,如下所示:
 setStatusesSelectBox: function (status_obj, lead_id) {
    var me = this;
    var statuses_list = '';
    var bg_color = status_obj.name == "new" ? me.new_status_row_bg_color : '';
    $.each(me.client_statuses, function (key, val) {
        if (val.id != status_obj.id) {
            if (typeof val.is_won !== "undefined" && val.is_won != 0) {
                statuses_list += "<option data-icon='fa fa-thumbs-o-up' value='" + val.id + "'>" + val.name + "</option>";
            } else if (typeof val.is_lost !== "undefined" && val.is_lost != 0) {
                statuses_list += "<option data-icon='fa fa-thumbs-o-down' value='" + val.id + "'>" + val.name + "</option>";
            } else {
                statuses_list += "<option value='" + val.id + "'>" + val.name + "</option>";
            }
        } else {
            if (typeof val.row_bg_color !== 'undefined') {
                bg_color = val.row_bg_color;
            }
            if (typeof status_obj.is_won !== "undefined" && status_obj.is_won != 0) {
                statuses_list += "<option data-icon='fa fa-thumbs-o-up' value='" + val.id + "' selected>" + val.name + "</option>";
            } else if (typeof status_obj.is_lost !== "undefined" && status_obj.is_lost != 0) {
                statuses_list += "<option data-icon='fa fa-thumbs-o-down' value='" + val.id + "' selected>" + val.name + "</option>";
            } else {
                statuses_list += "<option value='" + val.id + "' selected>" + val.name + "</option>";
            }
        }
    });
    statuses_list += "</select>";
    var select_start = "<select name='status' data-show-icon='true' data-row-bg='" + bg_color + "' class='form-control status-select' data-lead-id='" + lead_id + "'>";
    ;
    return select_start + statuses_list;
},

任何回答都会有所帮助,感激不尽。

刚刚添加了代码示例。 - benjah
3个回答

7

使用 exportOptions 的 'format.body' 回调函数来控制导出的数据。使用 dataTables API 查找每个 <select> 元素的当前选定值。这里针对第一列和 PDF 格式:

buttons: [
  { 
    extend : 'pdf',
    exportOptions : {
      format: {
        body: function( data, row, col, node ) {
          if (col == 0) {
            return table
              .cell( {row: row, column: col} )
              .nodes()
              .to$()
              .find(':selected')
              .text()
           } else {
              return data;
           }
        }
      }
    },
    ...
  }
]

在您的情况下,table 是表实例,即 me.dataTable_obj。现在只需要更改 if (col == 0) {,使其响应您拥有 <select>框的列(我不知道是哪些列)。


1
运行得非常好,但是我想指出参数的顺序实际上是错误的。目前正确的函数签名应该是“(data, row, col)”。 - v1n1akabozo
@v1n1akabozo 你是对的!已经更新答案为 function( data, row, col, node )。这也是在文档和这个官方示例中所述的方式。感谢你指出来!! - davidkonrad

2
如果您仅使用可见列的导出格式,则固定列索引将对您产生一些影响,因此在我的情况下有所帮助的是检查节点子项,如果它是选择项,则进行格式设置。
body: function(data, row, col,node) {
   var elementType = node.firstChild;
   if (elementType != null) {
         if (elementType.nodeName == "SELECT") return 
         $(elementType).find(':selected').text();
         else return data;
   }
   else return data

这个例子需要更好的代码格式。即使进行了清理,它也没有像预期的那样工作。但还是谢谢! - jonlink

0

感谢Mikhail Ushakov的启发。有一些简化代码和使其更加流畅的机会(在我的情况下),最大的问题是我的表格中几乎所有内容都是链接或选择器。对于链接,其他代码也捕获了链接的HTML而不是文本。在我的情况下,我还有一些奇怪的东西,比如表格,所以我必须预期每个节点中有多个子元素。此外,我选择不使用JQuery ;)

exportOptions: {
    format   : {
        body : (data, row, col, node) => {
            let node_text = '';
            const spacer = node.childNodes.length > 1 ? ' ' : '';
            node.childNodes.forEach(child_node => {
                const temp_text = child_node.nodeName == "SELECT" ? child_node.selectedOptions[0].textContent : child_node.textContent;
                node_text += temp_text ? `${temp_text}${spacer}` : '';
            });
            return node_text;
        }
    }
},

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