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 文件,我需要 Sab 和 Dom 列灰色
更新 * @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 中使用 B3
和 A5
值 - 例如:
$('c[r=B3] t', sheet).attr( 's', '25' );
补充说明:
DataTables cells().indexes()
函数描述 here。
如果超过 26 列,我的天真实现将失败:
var xlCol = String.fromCharCode(64 + tblCol);
但是如果需要的话,将它扩展到 Excel 列 "AA"、"AB" 等等应该不会太难。
如果你想在列(或行)级别而不是单元格级别工作,我还没有尝试过 - 但它应该是上面的稍微简单的版本。
我正在使用 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 文件,我需要 Sab 和 Dom 列灰色
更新 * @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 中使用 B3
和 A5
值 - 例如:
$('c[r=B3] t', sheet).attr( 's', '25' );
补充说明:
DataTables cells().indexes()
函数描述 here。
如果超过 26 列,我的天真实现将失败:
var xlCol = String.fromCharCode(64 + tblCol);
但是如果需要的话,将它扩展到 Excel 列 "AA"、"AB" 等等应该不会太难。
如果你想在列(或行)级别而不是单元格级别工作,我还没有尝试过 - 但它应该是上面的稍微简单的版本。