#js文件操作之——导出Excel (js-xlsx)
前阵子跟server同学讨论一个Excel导出的需求我说JS搞不定需要server来做被server同学强行打脸。
今天研究了下尼玛不光可以还很强大了
总结经验是害人的尤其是在发展迅速的前端圈儿and需要保持饥渴保持对新技术的敏感度。
注以下只探讨现代浏览器
1. 最简单的Excel导出
原理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。
base64形式的文件描述在js或者html中就是一个很长的base4字符串
blob形式的文件描述在js或者html中是一个URL形式的字符串他指向的是浏览器内存中的一个文件片段形如"blob:http://sheetjs.com/f999f57f-b79f-4293-a317-3bbf6ea58788"
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文件只有xls格式可以在Excel中打开xlsx不行。
2. 真正的Excel导出
是的这里有一个真正的二进制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文件的演化过程如下
2.1 网页上的table
2.2 sheet JSON
这里他用一个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"}}
2.3 未压缩的zip文件
源码中的“write_zip_type”方法它按照标准的电子表格格式协议把上述JSON转成了下面的样子。
如下很明显这里面包含了一些乱码和一些xml描述。
这里本着不求甚解的精神我咨询了一下我们部门的资深技术专家他搭眼一看说这是一个未压缩的zip。我也懒得输出一下zip来验证这个了他说是那就是了
PK
ÃæLÖ|ZZdocProps/core.xml
PK
ÃæLþù«44docProps/app.xml
SheetJSWorksheets1Sheet JSPK
ÃæLTÄ8ããxl/worksheets/sheet1.xml
ThisisaTestவணà®à¯à®à®®à¯à¸ªà¸§à¸±à¸ªà¸à¸µä½ 好ê°ì§ë§1234ClicktoeditcellsPK
Ãæ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.4 Blob URL
其实我最感兴趣的是这儿。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行代码恩不错开源万岁。
3. 总结
看起来先不说性能如何上面这些关键API利用一下js应该是可以导出很多种格式的文件了。
文本类的txt html js css xml
特定协议的文档pdf Excel cvs看起来word ppt 应该也可以了懒得去查了
其他各类二进制文件zip png jpg gif (不晓得是不是可以导出音视频…)
转载请注明出处 http://www.cnblogs.com/youryida