使用客户端 JavaScript 创建一个具有一些样式的 excel 文件(如果可能,使用 js-xlsx 库)

Create an excel file with a few styles using client side JavaScript (if possible using js-xlsx library)

我想创建一个 excel 文件(采用 .xlsx 格式)并使用 客户端JavaScript。我能够使用 js-xlsx 库创建示例文件。但我无法对其应用任何样式。至少一些基本样式包括背景颜色到header,粗体 for header 和 text wrapping for the cells are required.

js-xlsx 库文档说我们可以使用 Cell Object.

提供样式

我尝试使用单元格 object 提供样式,但它没有反映在下载的 .xlsx 文件中。我什至尝试读取 .xlsx 文件并使用 XLSX.write() 函数写回相同的文件。但它返回一个 excel 文件,根本没有任何样式。 理想情况下,我希望下载的文件与上传的文件具有相同的样式。 重新创建的文件中没有应用任何字体颜色或背景颜色。我使用 Excel 2013 来测试下载的文件。

请在下面找到上传前后的 excel 屏幕截图。

原始文件

已下载文件

代码如下。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<script type="text/javascript" src="xlsx.core.min.js"></script>
<script type="text/javascript" src="Blob.js"></script>
<script type="text/javascript" src="FileSaver.js"></script>

<script>

function s2ab(s) {
    var buf = new ArrayBuffer(s.length);
    var view = new Uint8Array(buf);
    for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
    return buf;
}   

/* set up XMLHttpRequest */
var url = "template-sample.xlsx";
var oReq = new XMLHttpRequest();
oReq.open("GET", url, true);
oReq.responseType = "arraybuffer";

oReq.onload = function(e) {
  var arraybuffer = oReq.response;

  /* convert data to binary string */
  var data = new Uint8Array(arraybuffer);
  var arr = new Array();
  for(var i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
  var bstr = arr.join("");

  /* Call XLSX */
  var workbook = XLSX.read(bstr, {type:"binary", cellStyles:true});

    console.log("read workbook");
    console.log(workbook);
  /* DO SOMETHING WITH workbook HERE */
    var wbout = XLSX.write(workbook, {bookType:'xlsx', bookSST:true, type: 'binary', cellStyles: true});
    saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), "template-download.xlsx");

}

function read(){
    oReq.send();    
}


</script>


</head>
<body>
    <button onclick="read()">save xlsx</button>
</body></html>

示例代码取自 here

我期待的是使用 js-xlsx 库或其他提供此功能的库为单元格提供样式的选项。我找到了一个名为 exceljs 的库,但是它需要 node js 来支持它。我正在寻找一个纯粹基于客户端的解决方案。这将用于基于 Cordova 的平板电脑和桌面应用程序。

经过一些研究,我找到了我自己的问题的解决方案。 我发现了一个名为 xlsx-style 的新库,用于提供样式。 xlsx-style 建立在 js-xlsx 之上,用于为生成的 excel 文件提供样式。可以使用单元格对象中的新属性将样式赋予单元格。

解释可在 npm xlsx-style 页面找到。

样式是使用与每个单元格关联的样式对象给出的。可以使用此样式对象指定字体、颜色、对齐方式等。

我在 github page 中添加了一个极简演示。 示例代码可在 github repository.

您可以在下面找到生成的 excel 页面的屏幕截图。

使用 xlsx-style,为每个集合 'WorkSheet' 并在 'WorkBook' 中添加之前添加样式。负责这个过程的属性是's'(样式)。

样本:

_.forEach(ws, (v, c) => {
    if (c !== '!ref') {
        if (header.indexOf(v.v) >= 0) {
            ws[c]['s'] = {
                fill: {
                patternType: 'solid', // none / solid
                fgColor: {rgb: 'FFD3D3D3'}
                }
            }
        }
    }
})

只有几个使用 xlsx-style 的例子,我并没有真正发现它们对快速获得我需要的东西有帮助。

这是我的解决方案,使用 xlsx-style 以及创建工作簿、设置单元格值和为该单元格着色所需的准系统。

我在获取正确的 xlsx.core.min.js 文件时遇到了一些困难,出于某种原因,并非所有版本都包含此文件。我最终直接从 Nithin Baby(anwsers 演示)复制

这是代码的简单版本

/* Object for the excel workbook data */
class Workbook {
    constructor() {
        this.SheetNames = [];
        this.Sheets = {};
    }
}

/* function for downloading the excel file */
function s2ab(s) {
    var buf = new ArrayBuffer(s.length);
    var view = new Uint8Array(buf);
    for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
    return buf;
}

// create the worksheet data
var ws_data = {}
var range = { s: { c: 0, r: 0 }, e: { c: 10, r: 10 } }; // worksheet cell range 
ws_data['!ref'] = XLSX.utils.encode_range(range); // set cell the range

var cell = { // create cell
    v: 'test', // value
    s: { // style
        fill: {
            fgColor: { rgb: "FF6666" } // red
        }
    }
}
ws_data[XLSX.utils.encode_cell({ c: 1, r: 1 })] = cell; // add the cell to the sheet data

// create workbook and download
var wb = new Workbook();
wb.SheetNames.push('test'); // create new worksheet
wb.Sheets['test'] = ws_data; // set workseet data to the cell data
var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'binary' }); //workbook output
saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), "Test Color.xlsx") // save workbook

有两点需要注意。

XLSX.utils.encode_cell({ c: 1, r: 1 }) 是他们将 excel 线分配给数字的方式。 例如:{ c: 1, r: 1 } == 'B2'

如果您可以下载 excel 文件,但未显示单元格数据,则很可能与工作表范围值有关。确保它匹配或大于数据量。 range = { s: { c: 0, r: 0 }, e: { c: 10, r: 10 } }; 其中 's' = 当前和 'e' = 我收集到的总数。

xlsx-style 有更多属性可以在创建单元格时设置,值得快速浏览一下以了解其中的内容。现在由您决定如何 create/style 输出所需的单元格并适当地设置范围值。

作为编写简单 *.xlsx 文件的另一种选择,我建议使用 write-excel-file 包。

https://npmjs.com/package/write-excel-file

它支持使用粗体、文本颜色、背景颜色、水平对齐方式、垂直对齐方式和溢出时的文本换行来设置样式单元格。

import writeXlsxFile from 'write-excel-file'

const data = [
  [{
    value: 'Row 1, Col 1',
    fontWeight: 'bold'
  }, {
    value: 'Row 1, Col 2',
    color: '#ffffff',
    backgroundColor: '#cc0000'
  }],
  [{
    value: 'Row 2, Col 1',
    align: 'right',
    alignVertical: 'top'
  }, {
    value: 'Row 2, Col 2. Long Text \n Multi-line',
    wrap: true
  }]
]

await writeXlsxFile(data, {
  fileName: 'file.xlsx'
})