Стиль DataTables Excel на основе класса ячейки - PullRequest
0 голосов
/ 17 июня 2020

Я использую плагин DataTables для экспорта ежемесячного календаря; Мне нужно установить стиль ячейки внутри файла Excel на основе класса соответствующей ячейки в представлении календаря DataTables . Я знаю, как стилизовать экспортированный файл Excel с использованием customize: function( xlsx, index ) {}, однако я не могу найти в примерах, которые я видел на форуме, способ установить стиль ячейки Excel на основе класса соответствующей ячейки. в представлении DataTables. Я создал свой собственный стиль 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, как вы можете найти в файле .xlsx, если вы измените расширение на .zip и затем разархивируете его. . Чтобы применить стили к ячейке 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, A C и так далее) , и мне нужен метод, чтобы различать некоторые из них, чтобы добавить другой стиль, как вы можете видеть, в заголовке 31 ячейка с календарем день / имя, и я хотел бы, чтобы столбцы с субботой и воскресеньем были с серым фоном, как в таблице данных.

Это datatable:

Datatables

And this is the excel file so far, i need the Sab and Dom columns to be gray

Exce file

UPDATE * with @ andrewjames решение и @ georg решение для двойных букв, размещенных здесь Преобразование чисел в буквы за пределами 26-символьного алфавита

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');
}

и вот результат:

Файл Exce

Как правильно говорит @andrewjames в своем ответе:

Моя наивная реализация завершится неудачно для более чем 26 столбцов:

Функция colName(n) решена эта проблема. Последний шаг - стилизовать ячейки с толстыми границами с их собственным стилем, но я могу считать это решенным.

1 Ответ

1 голос
/ 17 июня 2020

Допущения:

Похоже, у вас уже есть встроенный styles.xml, настроенный так, как вы хотите, и поэтому вы знаете, на какие значения индекса стиля ссылаться, из его <cellXfs> section.

Похоже, что недостающая часть знает, какие ячейки DataTables были заданы каким классам стилей CSS, поэтому вы можете выбрать соответствующие <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 был присвоен определенный стиль c, и переводит эти индексы ячеек в ячейку в стиле Excel r ссылки.

Итак, для следующих образцов данных ...

<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

Вы можете затем используйте значения B3 и A5 в нужных вам селекторах - например:

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

Дополнительные примечания :

Функция DataTables cells().indexes() описан здесь .

Моя наивная реализация завершится ошибкой для более чем 26 столбцов:

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

Но не должно быть слишком сложно расширить это для столбцов Excel «AA», «AB» и т. Д., Если необходимо.

Если вы хотите работать на уровне столбца (или строки), а не на уровне ячейки, я этого не пробовал, но это должно быть быть немного более простой версией вышеупомянутого.

...