DataTables Excel 样式基于单元格 class

DataTables Excel style based on cell class

我正在使用 DataTables plugin to export a monthly calendar view; I need to set a cell style inside the excel file based on the class of the corrisponding cell in the DataTables 日历视图。
我知道如何使用 customize: function( xlsx, index ) {} 设置导出的 excel 文件的样式,但是在我在论坛上看到的示例中,我找不到设置 [=70= 样式的方法] 单元格基于 DataTables 视图中相应单元格的 class。
我已经创建了自己的 xml 样式,如下所示:

customize: function( xlsx, index ) {
  var new_style = '<?xml version="1.0" encoding="UTF-8"?>'+
  '<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" '+
  'xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" '+
  'xmlns:x14ac="https://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" mc:Ignorable="x14ac">'+
    '<numFmts count="2">'+
      '<numFmt numFmtId="164" formatCode="0.0" />'+
      '<numFmt numFmtId="165" formatCode="\d\d\d" />'+
    '</numFmts>'+
    '<fonts count="4" x14ac:knownFonts="1">'+

    ...... a lot of stuff here ....

    '<extLst>'+
      '<ext xmlns:x14="https://schemas.microsoft.com/office/spreadsheetml/2009/9/main" uri="{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}">'+
        '<x14:slicerStyles defaultSlicerStyle="SlicerStyleLight1" />'+
      '</ext>'+
    '</extLst>'+
  '</styleSheet>';

这是一个 styles.xml,因为如果您将扩展名更改为 .zip,您可以在 .xlsx 文件旁边找到 而不是解压缩它。 要将样式应用到我正在做的 excel 单元格:

  xlsx.xl['styles.xml'] = $.parseXML(new_style);
  var sheet = xlsx.xl.worksheets['sheet1.xml'];

  $('row:first c', sheet).attr( 's', '1' );
  $('row:eq(1) c', sheet).attr( 's', '2' );
  $('row:eq(2) c', sheet).attr( 's', '3' );
}

我需要做的是:

     $('row:eq(3) c', sheet).hasClass('custom').attr( 's', '1' ); //not working

或:

    $('row c[r^="B"]', sheet).each( function () {
       if ( $(this).hasClass('custom') ) {
       $(this).attr( 's', '4' );
      }
    }); // not working

基本上我正在处理一排单元格(超过 30 个,所以我有 AA、AB、AC 等等) 我需要一种方法来区分一些其中添加不同的样式,如您所见 header 有 31 个带有日历的单元格 day/name 我希望星期六和星期日的列具有灰色背景,就像它们在数据中一样table table.

这是数据table:

这是目前的 excel 文件,我需要 SabDom 列灰色

更新 * @andrewjames solution and @georg solution for double letters posted here Convert numbers to letters beyond the 26 character alphabet

function colName(n) {
  var ordA = 'A'.charCodeAt(0);
  var ordZ = 'Z'.charCodeAt(0);
  var len = ordZ - ordA + 1;
  var s = "";
  while(n >= 0) {
    s = String.fromCharCode(n % len + ordA) + s;
    n = Math.floor(n / len) - 1;
  }
  return s;
}

var cellIndexes = tabellaOre.cells(".Sab, .Dom").indexes();

for (var i = 0; i < cellIndexes.length; i++) {
  var cellIndex = cellIndexes[i];
  var tblRow = cellIndex['row']+4; //changed to my needs
  var tblCol = cellIndex['column']; //removed +1
  // var xlCol = String.fromCharCode(64 + tblCol); changed with follow
  var xlCol = colName(tblCol);

  // .... previous stuff here, it was already in a for() loop, so still working

  $('row c[r='+xlCol+tblRow+']', sheet).attr('s','12');
}

这是结果:

正如@andrewjames 在他的回答中正确所说:

My naive implementation will fail for more than 26 columns:

colName(n) 函数解决了问题。
最后一步是用自己的样式为具有粗边框的单元格设置样式,但我认为这已经解决了。

假设:

听起来您已经按照自己的方式自定义了嵌入式 styles.xml,因此您从 <cellXfs> 部分知道要引用的样式索引值。

听起来好像缺失的部分是知道哪些 DataTables 单元格已被赋予哪种 CSS 样式 类,因此您可以 select 相关的 <cellXfs> 索引等效的 Excel 个单元格。

建议的方法:

这利用了 customize 函数可以传递 3 个变量的事实:

  • XML 文件 Excel
  • 表示按钮对象的对象
  • DataTable 实例

我们使用最后一个将 HTML 中的 类 映射到 Excel 中的单元格:

  var table = $('#example').dataTable({
    dom: 'Bfrtip',
    buttons: [
      {
        extend: 'excelHtml5',
        title: '', // no title row
        text: 'Excel',
        customize: function ( xlsx, btnObj, tableInst ){

          var cellIndexes = tableInst.cells(".mycustom").indexes();
          for (var i = 0; i < cellIndexes.length; i++) {
            var cellIndex = cellIndexes[i];
            var tblRow = cellIndex['row']+1; // adjusted from 0 indexed
            var tblCol = cellIndex['column']+1; // adjusted from 0 indexed
            var xlCol = String.fromCharCode(64 + tblCol); // DANGER: fails after Z (26 columns)
            alert('table row ' + tblRow + ' col ' + tblCol
                + ' maps to excel cell ref ' + xlCol + tblRow);
          }
        }
      }
    ]

  });

这不应用任何样式,它只是向您展示如何确定哪些 DataTable 单元格已被赋予特定样式,并将这些单元格索引转换为 Excel 样式的单元格引用。

因此,对于以下示例数据...

<table id="example" class="display nowrap dataTable cell-border" style="width:100%">
        <thead>
            <tr>
                <th>Head 1</th>
                <th>Head 2</th>
                <th>Head 3</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Row 1 column 1</td>
                <td>Row 1 column 2</td>
                <td>Row 1 column three</td>
            </tr>
            <tr>
                <td>Row 2 column 1</td>
                <td>Row 2 column 2</td>
                <td>Row 2 column 3</td>
            </tr>
            <tr>
                <td>Row 3 column 1</td>
                <td class="mycustom">Row 3 column 2</td>
                <td>Row 3 column 3</td>
            </tr>
            <tr>
                <td>Row 4 column 1</td>
                <td>Row 4 column 2</td>
                <td>Row 4 column 3</td>
            </tr>
            <tr>
                <td class="mycustom">Row 5 column 1</td>
                <td>Row 5 column 2</td>
                <td>Row 5 column 3</td>
            </tr>
        </tbody>
    </table>

...以上代码生成如下 2 个警报:

table row 3 col 2 maps to excel cell ref B3
table row 5 col 1 maps to excel cell ref A5

然后您可以在您需要的 select 中使用 B3A5 值 - 例如:

$('c[r=B3] t', sheet).attr( 's', '25' );

补充说明:

DataTables cells().indexes() 函数描述 here

如果超过 26 列,我的天真实现将失败:

var xlCol = String.fromCharCode(64 + tblCol);

但是如果需要的话,将它扩展到 Excel 列 "AA"、"AB" 等等应该不会太难。

如果你想在列(或行)级别而不是单元格级别工作,我还没有尝试过 - 但它应该是上面的稍微简单的版本。