#js文件操作之——导出Excel (js-xlsx)
前阵子跟server同学讨论一个Excel导出的需求我说JS搞不定需要server来做被server同学强行打脸。
今天研究了下尼玛不光可以还很强大了
总结经验是害人的尤其是在发展迅速的前端圈儿and需要保持饥渴保持对新技术的敏感度。
注以下只探讨现代浏览器
原理js可以通过base64或者blob把一个包含一个
的串导出成xx.xls格式。而Excel可以打开html文件。这样看起来就是一个成功的Excel导出。var tableHtml='only one
';//base64 URL形式文件下载var oa = document.createElement('a');
oa.href = 'data:application/vnd.ms-excel;base64,'+window.btoa(tableHtml);
oa.download = 'htmltable-base64.xls';//通过A标签 设置文件名oa.click();
文件在js中除了可以是base64也可以是一个blob。
blob形式的Excel导出如下
//blob URL形式文件下载var tableHtml='only one
';var excelBlob = new Blob([tableHtml], {type: 'application/vnd.ms-excel'});var oa = document.createElement('a');
oa.href = URL.createObjectURL(excelBlob);
oa.download = 'htmltable-blob.xls';
document.body.appendChild(oa);
oa.click();
毛病
是的这里有一个真正的二进制Excel文件导出。
他就是一万多star的js-xlsx地址 https://github.com/SheetJS/js-xlsx
我花了两个多小时追了好一阵子他的 https://github.com/SheetJS/js-xlsx/blob/master/xlsx.js 终于我搞明白他是什么原理了。
以下拿他的官方demo举例 http://sheetjs.com/demos/table.html。
从网页的table DOM到Excel文件的演化过程如下
这里他用一个json来描述了Excel表格中的A1,B1,C1等各个单元格。
{"Sheet JS":{"A1":{"t":"s","v":"This"},"B1":{"t":"s","v":"is"},"C1":{"t":"s","v":"a"},"D1":{"t":"s","v":"Test"},"A2":{"t":"s","v":"வணக்கம்"},"B2":{"t":"s","v":"สวัสดี"},"C2":{"t":"s","v":"你好"},"D2":{"t":"s","v":"가지마"},"A3":{"t":"n","v":1},"B3":{"t":"n","v":2},"C3":{"t":"n","v":3},"D3":{"t":"n","v":4},"A4":{"t":"s","v":"Click"},"B4":{"t":"s","v":"to"},"C4":{"t":"s","v":"edit"},"D4":{"t":"s","v":"cells"},"!ref":"A1:D4"}}
源码中的“write_zip_type”方法它按照标准的电子表格格式协议把上述JSON转成了下面的样子。
如下很明显这里面包含了一些乱码和一些xml描述。
这里本着不求甚解的精神我咨询了一下我们部门的资深技术专家他搭眼一看说这是一个未压缩的zip。我也懒得输出一下zip来验证这个了他说是那就是了
复制代码
PK
ÃæLÖ|ZZdocProps/core.xml
PK
ÃæLþù«44docProps/app.xml
SheetJS Worksheets 1 Sheet JS PK
ÃæLTÄ8ããxl/worksheets/sheet1.xml
This is a Test |
வணà®à¯à®à®®à¯ สวัสà¸à¸µ ä½ å¥½ ê°ì§ë§ |
1 2 3 4 |
Click to edit cells |
PK
ÃæLÜè¯ÏDDxl/workbook.xml
PK
ÃæL0kÞÞxl/theme/theme1.xml
PK
ÃæLUôZZ
xl/styles.xml
PK
ÃæL÷Â00[Content_Types].xml
PK
ÃæLJjùLL_rels/.rels
PKÃæLÐ?dÝ--xl/_rels/workbook.xml.rels
PKÃæLÖ|ZZdocProps/core.xmlPK
ÃæLþù«44docProps/app.xmlPK
ÃæLTÄ8ããëxl/worksheets/sheet1.xmlPK
ÃæLÜè¯ÏDDxl/workbook.xmlPK
ÃæL0kÞÞu xl/theme/theme1.xmlPK
ÃæLUôZZ
'xl/styles.xmlPK
ÃæL÷Â00 ,[Content_Types].xmlPK
ÃæLJjùLLj3_rels/.relsPK
ÃæLÐ?dÝ--ß5xl/_rels/workbook.xml.relsPK >D8
其实我最感兴趣的是这儿。2.3中的一大坨字符串通过 Uine8Array转成了无符号数组并通过new Blob方法转成了二进制文件片段关键代码如下
function blobify(strData) { var buf = new ArrayBuffer(strData.length), view = new Uint8Array(buf); for (var i=0; i!=strData.length; ++i) view[i] = strData.charCodeAt(i) & 0xFF; return buf;
}var excelBlob = new Blob([blobify(data)], {type:"application/octet-stream"});var blobURL=URL.createObjectURL(excelBlob);
最后通过URL.createObjectURL方法把blob转成了肉眼可见的js和HTML中可以看到的Blob URL如下
blob:http://sheetjs.com/f999f57f-b79f-4293-a317-3bbf6ea58788
尼玛一个html转Excel的库js有20170行代码恩不错开源万岁。
看起来先不说性能如何上面这些关键API利用一下js应该是可以导出很多种格式的文件了。
文本类的txt html js css xml
特定协议的文档pdf Excel cvs看起来word ppt 应该也可以了懒得去查了
其他各类二进制文件zip png jpg gif (不晓得是不是可以导出音视频…)
转载请注明出处 http://www.cnblogs.com/youryida