需求:完整导入导出excel, 于是又一通Google。
发现了以下玩意
前端解析excel/nodejs也可以 https://github.com/SheetJS/js-xlsx
前端呈现excel样式,不过Jquery的 https://handsontable.com
如果有angular的就好了,想着ui-grid的可以, 但需要做的工作太多, 时间紧任务重, 还是拿现成的吧(不是我的风格)
xlsx入门
xlsx支持以下格式读取
- Excel 2007+ XML Formats (XLSX/XLSM)
- Excel 2007+ Binary Format (XLSB)
- Excel 2003-2004 XML Format (XML “SpreadsheetML”)
- Excel 97-2004 (XLS BIFF8)
- Excel 5.0/95 (XLS BIFF5)
- OpenDocument Spreadsheet (ODS)
支持写入文件的格式
- XLSX
- CSV (and general DSV)
- JSON and JS objects (various styles)
安装
npm安装
npm install xlsx
浏览器引入
<script lang="javascript" src="dist/xlsx.core.min.js"></script>
bower安装
bower install js-xlsx
可选模块
node版本自动加载依赖。
有些模块过大,却在特定场景使用,所以没放进核心库中。为了浏览器能够使用必须引入
<!-- international support from https://github.com/sheetjs/js-codepage -->
<script src="dist/cpexcel.js"></script>
<!-- ODS support -->
<script src="dist/ods.js"></script>
dist目录下生成好了压缩版本
包含全部功能的单文件版本dist/xlsx.full.min.js
低版本js标准兼容性
xlxs.js使用的ES5标准, 低版本的浏览器需要Polyfills支持。引入shim即可
<script type="text/javascript" src="/path/to/shim.js"></script>
要在xlxs之前加载
解析Workbooks
一些概念
workbook 指整个excel, 读取excel文件得到的对象
worksheet 指excel中的一个表, 一个excel至少一张表
cell 指单元格
node读取
XLSX = require('xlsx');
var workbook = XLSX.readFile('test.xlsx');
ajax读取,兼容低版本的请看http://oss.sheetjs.com/js-xlsx/ajax.html
/* set up XMLHttpRequest */
var url = "test_files/formula_stress_test_ajax.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"});
/* DO SOMETHING WITH workbook HERE */
}
oReq.send();
HTML5拖拽,使用readAsBinaryString读取
/* set up drag-and-drop event */
function handleDrop(e) {
e.stopPropagation();
e.preventDefault();
var files = e.dataTransfer.files;
var i,f;
for (i = 0, f = files[i]; i != files.length; ++i) {
var reader = new FileReader();
var name = f.name;
reader.onload = function(e) {
var data = e.target.result;
/* if binary string, read with type 'binary' */
var workbook = XLSX.read(data, {type: 'binary'});
/* DO SOMETHING WITH workbook HERE */
};
reader.readAsBinaryString(f);
}
}
drop_dom_element.addEventListener('drop', handleDrop, false);
HTML5 输入框使用readAsBinaryString读取
function handleFile(e) {
var files = e.target.files;
var i,f;
for (i = 0, f = files[i]; i != files.length; ++i) {
var reader = new FileReader();
var name = f.name;
reader.onload = function(e) {
var data = e.target.result;
var workbook = XLSX.read(data, {type: 'binary'});
/* DO SOMETHING WITH workbook HERE */
};
reader.readAsBinaryString(f);
}
}
input_dom_element.addEventListener('change', handleFile, false);
真累…
记些要点
###接口
XLSX.utils.encode_row(0) -> '1'
XLSX.utils.decode_row('1') -> 0
XLSX.utils.encode_col(4) -> 'E'
XLSX.utils.decode_col('E') -> 4
XLSX.utils.encode_cell({c:0,r:2}) -> 'A3'
XLSX.utils.decode_cell('C4') -> { c: 2, r: 3 }
XLSX.utils.encode_range({s:{c:0,r:1},e:{c:2,r:4}}) -> 'A2:C5'
XLSX.utils.decode_range('A5:C6') -> {s:{c:0,r:4},e:{c:2,r:5}}
###Workbook / Worksheet / Cell 对象描述
####一般结构
这样表示一个单元格地址 {c:C, r:R}, 大写C和R是0开始的索引值。B5单元格的表示方法就是{c:1, r:4} c就是列, r就是行。
这样表示一个单元格范围 {s:S, e:E}, 范围里S是第一个单元格, E是最后一个单元格。像A3:B7对应就是{s:{c:0, r:2}, e:{c:1, r:6}}。这样就知道哪些单元格是合并的了
单元格对象
| Key | 描述 |
|---|---|
v |
raw value (see Data Types section for more info) |
w |
格式化文本 (如果支持) |
t |
数据类型: b Boolean, n 数字, e 错误, s 字符串, d 日期 |
f |
公式 (如果支持) |
r |
富文本编码 (如果支持, node读出来似乎不支持, 乱码) |
h |
HTML 渲染的富文本 (如果支持) |
c |
comments associated with the cell ** 没见过 |
z |
number format string associated with the cell (if requested) |
l |
单元格的链接地址 (.Target holds link, .tooltip is tooltip) |
s |
the style/theme of the cell (if applicable)单元格样式(支持有限) |
###Worksheet Object
这些特殊字段都以!开头
!ref 表格的范围
最后的最后发现对样式的支持完全没有…. 看issues也是….唉。
隆重介绍一下这个fork
https://github.com/protobi/js-xlsx
一下安静了。。。谁用谁知道