使用客户端JavaScript(如果可能,使用js-xlsx库)创建一个带有几种样式的Excel文件。

28
我想创建一个 Excel 文件(在.xlsx格式中)并使用客户端 JavaScript使其可供下载。我能够使用js-xlsx库创建示例文件。但我无法应用任何样式。至少需要一些基本的样式,包括标题的背景颜色,标题的粗字体和单元格的文本换行js-xlsx库文档说我们可以使用Cell Object提供样式。
我尝试使用单元格对象给出样式,但它没有反映在下载的 .xlsx 文件中。我甚至尝试读取 .xlsx 文件并使用XLSX.write()函数将同一文件写回。但它返回了一个没有任何样式的 Excel 文件。理想情况下,我希望下载的文件具有上传文件的相同样式。重新创建的文件中没有应用字体颜色或背景颜色。我使用Excel 2013测试下载的文件。
请参见以下 Excel 截图,上传前和上传后。 原始文件 enter image description here 下载的文件 enter image description here 代码如下。
<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>

示例代码来自这里

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


在不使用任何库的情况下下载Excel文件,请参考此链接:[https://dev59.com/RWMm5IYBdhLWcg3wIsbj#52552921]。 - Pulkit Aggarwal
4个回答

35
经过一番调查,我找到了解决自己问题的方法。我发现了一个名为 xlsx-style 的新库,用于添加样式。 xlsx-style 基于 js-xlsx 构建,用于向生成的 Excel 文件添加样式。可以使用单元格对象中的新属性来给单元格添加样式。
有关说明可在 npm xlsx-style 页面上找到。
使用与每个单元格关联的样式对象来实现样式。可以使用此样式对象来设置字体、颜色、对齐等内容。
我在github页面中添加了一个极简演示。示例代码位于此github存储库中。
以下是生成的 Excel 页面的屏幕截图。 enter image description here

1
我已经成功实现了这个功能。但是,如果你能在这里发布你的工作代码片段,那就更好了,因为缺乏示例。这将对其他人有所帮助。谢谢。 - gihan-maduranga
1
@gihan 我已经在我的 Github 存储库中添加了一个示例。任何人都可以将其变得更好。 - Nithin Baby
@Nitin Baby,我需要在Ionic中创建类似的Excel表格。你有任何想法吗?我尝试了但没有成功。 - user320676
感谢 @DarlanDieterich。你的点赞是我的动力。我很高兴这篇帖子对许多人有用。在找到这样的解决方案之前,我尝试了很多次。但现在我很开心。 - Nithin Baby
@NithinBaby 未来是共享知识!谢谢,伙计! - Darlan Dieterich
显示剩余3条评论

4
作为编写简单的 *.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'
})

1
由于 xlsx-style 无法在列上设置宽度,而 xlsx 则完全没有样式。因此,write-excel-file 对我来说是完美的解决方案。感谢您的提示。 - StevenSiebert
我正在使用这个write-excel-file,但是无法将图片添加到单元格中。有人可以建议一下如何添加图片吗?我在官方网站上找不到任何相关文档。 - undefined
我稍微研究了一下在电子表格中插入图片的主题,并在这份文档中描述了实施注意事项:https://gitlab.com/catamphetamine/write-excel-file/-/blob/main/docs/IMAGES.md?ref_type=heads目前,我不认为我会去实施它。但如果有人想要的话,文档中包含了说明。 - undefined

1

这里只有一些使用xlsx-style的例子,但我并没有真正找到清晰或有帮助的内容,以便快速获取我所需的内容。

以下是我使用xlsx-style的解决方案,仅包含创建工作簿,设置单元格值和对单元格进行着色所需的基本要素。

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

这是代码的简单版本。

/* 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 创建单元格时可以设置更多属性,值得快速浏览以了解其中内容。现在轮到您想要创建/样式化所需单元格并适当地设置范围值。

1
默认的 xlsx.core.min.js 文件也是我样式没有正确应用的原因。最终我复制了 Nithin 的文件,这样就可以正常工作了。 - Rachel Nicolas

0

使用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'}
                }
            }
        }
    }
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接