上篇文章中提到关于xlsx改造冻结窗格的代码,我是怎么知道要加pane的呢,加下来就把我的心路历程记录一下。
我改造之前也是没有头绪的,我网上查了很多,只告诉我如何使用,但源码里没有针对!freeze的处理,所以即便把!freeze传过去也是无用的。于是我想既然js可以实现excel的导出,那应该有办法能实现,只是原作者写到pro版里了,那么我能不能加上呢,如何加呢?
我先贴上部分代码
- // 冻结第一行和第一列:
- worksheet['!freeze'] = {
- xSplit: "0", //冻结列
- ySplit: "1", //冻结行
- // topLeftCell: "A2", //在未冻结区域的左上角显示的单元格,默认为第一个未冻结的单元格
- state: "frozen"
- }
-
- var wbout = XLSX.write(workbook, {
- bookType: 'xlsx',
- bookSST: false,
- type: 'binary'
- })
首先我打印了wbout,发现是一个二进制文件,然后找到xlsx.write的write
- // 部分代码
- ...
- XLSX.parse_zip = parse_zip;
- XLSX.read = readSync; //xlsread
- XLSX.readFile = readFileSync; //readFile
- XLSX.readFileSync = readFileSync;
- XLSX.write = writeSync;
- XLSX.writeFile = writeFileSync;
- XLSX.writeFileSync = writeFileSync;
- XLSX.writeFileAsync = writeFileAsync;
- XLSX.utils = utils;
- XLSX.writeXLSX = writeSyncXLSX;
- XLSX.writeFileXLSX = writeFileSyncXLSX;
- XLSX.SSF = SSF;
然后找到writeSync方法 -》 write_zip_type -》 write_zip -》write_zip_xlsx
- function write_zip(wb, opts) {
- console.log('write_zip', opts.bookType)
- if(opts.bookType == "ods") return write_ods(wb, opts);
- if(opts.bookType == "numbers") return write_numbers_iwa(wb, opts);
- if(opts.bookType == "xlsb") return write_zip_xlsxb(wb, opts);
- return write_zip_xlsx(wb, opts);
- }
关键点就在write_zip_xlsx方法中
在write_zip_xlsx方法中,我们找到xl/worksheets/sheet的下面的write_ws_xml方法,
write_ws_xml方法返回的就是一段字符串,就是我们要导出的excel的内容
- // 部分代码
- ...
- var wsrels = {'!id':{}};
- var ws = wb.Sheets[wb.SheetNames[rId-1]];
- var _type = (ws || {})["!type"] || "sheet";
- switch(_type) {
- case "chart":
- /* falls through */
- default:
- f = "xl/worksheets/sheet" + rId + "." + wbext;
- zip_add_file(zip, f, write_ws_xml(rId-1, opts, wb, wsrels));
- ct.sheets.push(f);
- add_rels(opts.wbrels, -1, "worksheets/sheet" + rId + "." + wbext, RELS.WS[0]);
- }
这里我们在write_zip_xlsx方法的xl/worksheets/sheet的下面打印一下console.log(write_ws_xml(rId-1, opts, wb, wsrels))
这里我们可以看见返回的是一个类似xml格式的字符串
(这里我加上!freeze代码之后的打印结果,没加之前是没有
这串字符的)
我们就想了excel的原理是不是就是xml格式呢,我怎么往里面添加上它能识别的标签呢??
带着疑问,我查找了下面的资料:
Excel文件的本质:一个包含XML、图片文件的压缩文件夹-压缩文件-上犹电脑信息网
根据资料,我试着本地新建一个excel文件,分别一次设置冻结窗口,一个不设置,然后将文件后缀改为zip、解压,得到的目录和资料中的一致,对比两个xl/worksheets/sheet1.xml的区别,发现是
- //部分代码
- ...
- // 冻结窗口
- var pane = null;
- var freeze = ws['!freeze'];
- console.log(freeze)
-
- if (freeze !== undefined) {
- pane = writextag('pane', null, {
- xSplit: freeze.xSplit, // 冻结列
- ySplit: freeze.ySplit, // 冻结行
- topLeftCell: freeze.topLeftCell, // 在未冻结区域的左上角显示的单元格,默认为第一个未冻结的单元格
- activePane: freeze.activePane,
- state: freeze.state || 'frozen'
- })
- }
- return writextag("sheetViews", writextag("sheetView", pane, sview), {});
以上就是完整的流程,改造冻结窗口只是示例,通过类似的过程,我们可以改造成我们想要的其他格式。