使用js-xlsx处理excel

需求:完整导入导出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

一下安静了。。。谁用谁知道