excel - 基于单元格类的 DataTables Excel 样式
问题描述
我正在使用DataTables 插件导出月历视图;我需要根据DataTables日历视图中对应单元格的类在 Excel 文件中设置单元格样式。
我知道如何设置导出的 excel 文件的样式,customize: function( xlsx, index ) {}
但是在我在论坛上看到的示例中,我找不到一种基于 DataTables 中 corrispondig 单元格的类来设置 excel 单元格样式的方法看法。
我创建了自己的 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
可以在文件中找到此文件
。要将样式应用于我正在执行的 excel 单元格:.xlsx
.zip
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 等),我需要一种方法来区分其中一些以添加不同的样式,如您所见标题有31 个带有日历日/名称的单元格,我希望周六和周日的列具有灰色背景,就像它们在数据表中一样。
这是数据表:
这是到目前为止的 excel 文件,我需要将Sab和Dom列设为灰色
更新 * 使用@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');
}
这是结果:
正如@andrewjames 在他的回答中正确所说:
我的幼稚实现将失败超过 26 列:
该colName(n)
功能解决了这个问题。
最后一步是用自己的样式设置粗边框的单元格,但我可以认为这已经解决了。
解决方案
假设:
听起来您已经styles.xml
按照您想要的方式自定义了嵌入式,因此您可以从其<cellXfs>
部分中知道要引用的样式索引值。
听起来好像缺少的部分是知道哪些 DataTables 单元格已被赋予了哪些 CSS 样式类,因此您可以<cellXfs>
为等效的 Excel 单元格选择相关索引。
建议的方法:
这利用了customize
函数可以传递 3 个变量的事实:
- Excel 的 XML 文件
- 表示按钮对象的对象
- 数据表实例
我们使用最后一个将 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
然后,您可以在需要的选择器中使用B3
andA5
值 - 例如:
$('c[r=B3] t', sheet).attr( 's', '25' );
附加说明:
此处描述了DataTablescells().indexes()
函数。
我的幼稚实现将失败超过 26 列:
var xlCol = String.fromCharCode(64 + tblCol);
但是,如果需要,对 Excel 列“AA”、“AB”等进行扩展应该不会太难。
如果您想在列(或行)级别而不是单元格级别工作,我没有尝试过 - 但它应该是上面的一个稍微简单的版本。
推荐阅读
- javascript - 创建一个接受函数并返回带有时间戳的函数的函数
- angular - 如何使用 RxJS 6.4.0 强制应用程序以角度顺序执行 3 个 observable?
- azure-functions - 天蓝色函数队列触发器配置
- apache - 当代理传递设置为后端快速服务器时访问 apache http://your.server.name/server-status
- c# - UWP PointerEnter 和 PointerLeave 未附加到树中的外部元素
- python - 在循环中添加动态大小的子图
- sql-server - 对于具有数百万条记录的表,查询非常慢。什么是正确的处理方法
- python - 将大量jpeg图像批量转换为png
- javascript - TypeError: undefined is not an object (评估 '_props$checkWeather.err')
- bash - 我可以使用 `sets` 将 configspec 设置为变量吗?