【问题标题】:datatable remove column on export to pdf and excel数据表删除导出到 pdf 和 excel 的列
【发布时间】:2021-10-24 00:56:42
【问题描述】:

在导出到 pdf、excel 之前删除列时出现问题。 第二个问题是,由于此列,列的反向无法正常工作 这是我使用的代码

$(document).ready(function(){
            var arrayCol = new Array();
            var table = $('#example').DataTable({
                dom: 'B<"top"iflp<"clear">>rt<"bottom"ip<"clear">>',
                initComplete:function (  ) {
                    var len = this.api().columns().count();
                    var array =  Array.from(Array(len).keys());
                    arrayCol = array.reverse();
                  },
            buttons: [
      { 
        extend: 'pdf',
        text: 'To PDF',
        exportOptions: {
          rows: function ( idx, data, node ) {
            return data.reverse();
          },
          format: {
          columns: ':visible:not(.not-export-col)', 
            header: function ( data, idx, node ) {
              var headers = $('#example').DataTable().table().header();
              var reversedHeaders = headers.innerText.split('\t').reverse();
              return reversedHeaders[idx];
            }
          }
        }
      },
               { 
        extend: 'excel',
        text: 'exel',
        exportOptions: {
        columns: ':visible:not(.not-export-col)', 
          rows: function ( idx, data, node ) {
            return data.reverse();
          },
          format: {
            header: function ( data, idx, node ) {
              var headers = $('#example').DataTable().table().header();
              var reversedHeaders = headers.innerText.split('\t').reverse();
              return reversedHeaders[idx];
            }
          }
        }
      }
    ]
                });
        });

here 是一个活生生的例子

【问题讨论】:

    标签: javascript jquery datatables


    【解决方案1】:

    您可以扩展使用 here 的方法来处理抑制一个或多个您不想导出的列的额外要求。

    您对列选择器的使用效果很好:

    columns: ':visible:not(.not-export-col)
    

    为了构建我们要导出的标头列表,可以使用initComplete 函数(因此我们只执行此过程一次)。

    我们还可以使用initComplete 函数来构建我们不想想要导出的列索引数组:

    var ignorePositions = []; // column indexes of data NOT to be exported
    var reversedHeaders = []; // with "not-export" headings removed
    

    功能:

    initComplete:function (  ) {
      var thead = $( '#example' ).DataTable().table().header();
      var tds = $( thead ).find( 'th' ).each(function( index ) {
        if ( ! $( this ).hasClass('not-export-col') ) {
          reversedHeaders.push( $( this ).text() );
        } else {
          ignorePositions.push(index);
        }
      });
      reversedHeaders.reverse(); // to give us the export order we want
      ignorePositions.reverse(); // reversed for when we splice() - see below
    }
    

    上面的代码填充了两个数组:

    • reversedHeaders - 包含我们将导出的那些列的标题列表(反向)。
    • ignorePositions - 包含要忽略的列索引列表。在我们的示例中,唯一这样的列是最后一列(索引 6)。

    那么我们就可以在修改后的exportOptions代码中使用上面的数组了:

    exportOptions: {
      rows: function ( idx, data, node ) {
        var keepRowData = [];
        // we splice to remove those data fields we do not want to export:
        ignorePositions.forEach(idx => data.splice(idx, 1) );
          return data.reverse();
      },
      columns: ':visible:not(.not-export-col)',
      format: { 
        header: function ( data, idx, node ) {
          return reversedHeaders[idx];
        }
      }
    }
    

    唯一棘手的部分是需要使用splice 直接更改原始data 数组。这会从原始数据数组中删除每个不需要的元素,而不创建新的数据数组。

    把它们放在一起:

    <!doctype html>
    <html>
    <head>
      <meta charset="UTF-8">
      <title>Demo</title>
      <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
      <script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
      <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
      <link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
    
      <!-- buttons -->
      <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.6.5/css/buttons.dataTables.min.css"/> 
      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jszip/2.5.0/jszip.min.js"></script>
      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
      <script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/dataTables.buttons.min.js"></script>
      <script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/buttons.colVis.min.js"></script>
      <script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/buttons.flash.min.js"></script>
      <script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/buttons.html5.min.js"></script>
      <script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/buttons.print.min.js"></script>
    
    </head>
    
    <body>
    
    <div class="container">
          <table id="example" class="display nowrap" width="100%">
            <thead>
              <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Age</th>
                <th>Start date</th>
                <th>Salary</th>
                <th class="not-export-col">opr</th>
              </tr>
            </thead>
    <!--
            <tfoot>
              <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Age</th>
                <th>Start date</th>
                <th>Salary</th>
                <th class="not-export-col">opr</th>
              </tr>
            </tfoot>
    -->
            <tbody>
              <tr>
                <td>Tiger Nixon</td>
                <td>System Architect</td>
                <td>Edinburgh</td>
                <td>61</td>
                <td>2011/04/25</td>
                <td>$3,120</td>
                <td><a href="www.google.com"><i class="wb-edit"></i></a></td>
              </tr>
    <!--
              <tr>
                <td>Garrett Winters</td>
                <td>Director</td>
                <td>Edinburgh</td>
                <td>63</td>
                <td>2011/07/25</td>
                <td>$5,300</td>
                <td><a href="www.google.com"><span class="iconify" data-icon="fa:edit"></span></a></td>
              </tr>
              <tr>
                <td>Ashton Cox</td>
                <td>Technical Author</td>
                <td>San Francisco</td>
                <td>66</td>
                <td>2009/01/12</td>
                <td>$4,800</td>
                <td><a href="www.google.com"><span class="iconify" data-icon="fa:edit"></span></a></td>
              </tr>
              <tr>
                <td>Cedric Kelly</td>
                <td>Javascript Developer</td>
                <td>Edinburgh</td>
                <td>22</td>
                <td>2012/03/29</td>
                <td>$3,600</td>
                <td><a href="www.google.com"><span class="iconify" data-icon="fa:edit"></span></a></td>
              </tr>
              <tr>
                <td>Jenna Elliott</td>
                <td>Financial Controller</td>
                <td>Edinburgh</td>
                <td>33</td>
                <td>2008/11/28</td>
                <td>$5,300</td>
                <td><a href="www.google.com"><span class="iconify" data-icon="fa:edit"></span></a></td>
              </tr>
              <tr>
                <td>Donna Snider</td>
                <td>System Architect</td>
                <td>New York</td>
                <td>27</td>
                <td>2011/01/25</td>
                <td>$3,120</td>
                <td><a href="www.google.com"><span class="iconify" data-icon="fa:edit"></span></a></td>
              </tr>
    -->
            </tbody>
          </table>
        </div>
    <script>
    
    $(document).ready(function() {
      var ignorePositions = []; // column indexes of data NOT to be exported
      var reversedHeaders = []; // with "not-export" headings removed
    
      var table = $('#example').DataTable( {
        dom: 'B<"top"iflp<"clear">>rt<"bottom"ip<"clear">>',
        initComplete:function (  ) {
          var thead = $( '#example' ).DataTable().table().header();
          var tds = $( thead ).find( 'th' ).each(function( index ) {
            if ( ! $( this ).hasClass('not-export-col') ) {
              reversedHeaders.push( $( this ).text() );
            } else {
              ignorePositions.push(index);
            }
          });
          reversedHeaders.reverse(); // to give us the export order we want
          ignorePositions.reverse(); // reversed for when we splice() - see below
        },
        buttons: [
          { 
            extend: 'pdf',
            text: 'To PDF',
            exportOptions: {
              rows: function ( idx, data, node ) {
                var keepRowData = [];
                // we splice to remove those data fields we do not want to export:
                ignorePositions.forEach(idx => data.splice(idx, 1) );
                return data.reverse();
              },
              columns: ':visible:not(.not-export-col)',
              format: { 
                header: function ( data, idx, node ) {
                  return reversedHeaders[idx];
                }
              }
            }
          }
        ]
      } );
    } );
    
    </script>
    
    </body>
    </html>
    

    表格数据,如下图:

    像这样导出为 PDF:


    最后的笔记:

    1. 我只在上面的代码中实现了 PDF 按钮。 Excel 按钮代码也需要添加,但应该相同。

    2. 我在我的代码中注释掉了 HTML 表的 &lt;tfoot&gt; 部分。我认为这意味着您还需要在您的实现中添加footer: function() { ... },以匹配header: function() { ... } 代码。我假设如下(但我没有对此进行测试):

    format: { 
      header: function ( data, idx, node ) {
        return reversedHeaders[idx];
      },
      footer: function ( data, idx, node ) {
        return reversedHeaders[idx];
      }
    }
    

    更新

    我看到了烦人的警报。这是由我的代码引起的,它改变了数据行的长度(当它拼接出一个元素时)。

    第二个问题是,一旦反转了一行,它就会保持反转 - 因此,在下一次导出时,导出的数据的顺序是错误的。

    解决这两个问题很麻烦,而且我提出的解决方案是有限的:

    我的解决方案假设您只想隐藏最后一列

    它还依赖于您能够检测到何时反转行 - 在我的情况下,这是通过检查行数据的最终位置中的特定值来完成的 - 同样,这不是一个非常可靠的方法 - 但它是我目前能想到的唯一方法。

    这是更新后的代码:

    $(document).ready(function() {
      var exportPositions = []; // column indexes of data NOT to be exported
      var ignorePositions = []; // column indexes of data NOT to be exported
      var reversedHeaders = []; // with "not-export" headings removed
    
      var table = $('#example').DataTable( {
        dom: 'B<"top"iflp<"clear">>rt<"bottom"ip<"clear">>',
        initComplete:function (  ) {
          var thead = $( '#example' ).DataTable().table().header();
          var tds = $( thead ).find( 'th' ).each(function( index ) {
            if ( ! $( this ).hasClass('not-export-col') ) {
              reversedHeaders.push( $( this ).text() );
              exportPositions.push(index);
            } else {
              ignorePositions.push(index);
            }
          });
          reversedHeaders.reverse(); // to give us the export order we want
          reversedHeaders.push('');
          ignorePositions.reverse(); // reversed for when we splice() - see below
        },
        buttons: [
          { 
            extend: 'pdf',
            text: 'To PDF',
            exportOptions: {
              rows: function ( idx, data, node ) {
                if (data[data.length - 1] === '~') {
                  data.reverse(); // un-reverse an already reversed record
                  data.push(data.splice(0, 1)[0]); // move first element to end of the array
                }
                // we splice to remove those data fields we do not want to export:
                ignorePositions.forEach(idx => {
                  data.splice(idx, 1);
                } );
                data.reverse();
                ignorePositions.forEach(idx => {
                  data.push('~'); // pad the array back to its original length
                } );
                return data;
              },
              columns: exportPositions, // here we use the array we built earlier
              format: { 
                header: function ( data, idx, node ) {
                  return reversedHeaders[idx];
                }
              }
            }
          }
        ]
      } );
    } );
    

    如果您的实际实现需要隐藏多个列,那么这种方法可能不适合您。如果我对更强大的解决方案有任何想法,我会更新答案。

    【讨论】:

    • 第一次导出效果很好,第二次导出不行,出现烦人的提示怎么解决
    • 我明白你的意思 - 我已经提供了一些更新。
    猜你喜欢
    • 2014-12-05
    • 2018-02-13
    • 2014-11-30
    • 2015-02-07
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 2017-11-29
    • 1970-01-01
    相关资源
    最近更新 更多