diff --git a/README.md b/README.md index 754d540..f0b0072 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Features: * Custom cell border styles(such as thin,medium). * Custom cell font styles(such as font-family,bold). * Custom cell border styles and merge cells. +* Custom cell number formats. * Text rotation in cells. ## Getting Started @@ -100,21 +101,23 @@ workbook.save(function(err){ Cancel to make current workbook,drop all data. -### Sheet.set(col, row, str) +### Sheet.set(col, row, val) Set the cell data. * `col` - (Number) Cell column index(start with 1). * `row` - (Number) Cell row index(start with 1). -* `str` - (String) Cell data. +* `val` - (String/Number/Date) Cell data. No returns. +Notes: A date is stored as a number, so the appropriate cell format should also be set. + Example: ```javascript -sheet1.set(1,1,'Hello '); -sheet1.set(2,1,'world!'); +sheet1.set(1, 1, 'Hello world!'); +sheet1.set(2, 1, 123.456); ``` ## Sheet.width(col, width) @@ -129,6 +132,18 @@ sheet1.width(1, 30); sheet1.height(1, 20); ``` +## Sheet.format(col, row, format) + +Set cell number format + +* `format` - (String) format string + +Example: + +```javascript +sheet1.format(2, 1, '0.000'); +``` + ## Sheet.align(col, row, align) ## Sheet.valign(col, row, valign) ## Sheet.wrap(col, row, wrap) diff --git a/lib/msexcel-builder.js b/lib/msexcel-builder.js index 71773e8..0cebc19 100644 --- a/lib/msexcel-builder.js +++ b/lib/msexcel-builder.js @@ -1,7 +1,10 @@ /* - MS Excel 2007 Creater v0.0.1 + MS Excel 2007 Creater v0.0.2 Author : chuanyi.zheng@gmail.com History: 2012/11/07 first created + 2015/06/05 added support for numbers + 2015/06/09 added support for number formats + 2015/06/10 added support for dates */ var ContentTypes, DocPropsApp, SharedStrings, Sheet, Style, Workbook, XlRels, XlWorkbook, exec, fs, opt, path, tool, xml, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; @@ -39,6 +42,18 @@ tool = { } return getCellAdr(i); }, + + jd2ed: function(jd) { + var ed = 25568 + (jd.getTime() - (jd.getTimezoneOffset() * 1000 * 60)) / 1000 / 60 / 60 / 24; + if ((jd.getFullYear() === 1900) && (jd.getMonth() === 0) && (jd.getDate() === 1)) { + ed--; + } + if (ed > 59) { + ed++; + } + return ed; + }, + copy: function(origin, target) { var f, files, oCur, s, tCur, _i, _len, _results; if (existsSync(origin)) { @@ -322,7 +337,8 @@ Sheet = (function() { this.data[i] = {}; for (j = 1, _ref2 = this.cols; 1 <= _ref2 ? j <= _ref2 : j >= _ref2; 1 <= _ref2 ? j++ : j--) { this.data[i][j] = { - v: 0 + v: null, + t: '' }; } } @@ -332,10 +348,27 @@ Sheet = (function() { this.styles = {}; } - Sheet.prototype.set = function(col, row, str) { - if ((str != null) && str !== '') { - return this.data[row][col].v = this.book.ss.str2id('' + str); + Sheet.prototype.set = function(col, row, value) { + if ((typeof value) === 'string') { + if ((value != null) && value !== '') { + this.data[row][col].v = this.book.ss.str2id('' + value); + } + this.data[row][col].t = 's'; + return value + } + if ((typeof value) === 'number') { + this.data[row][col].v = value; + this.data[row][col].t = 'n'; + return value } + if ((typeof value) === 'object') { + if(Object.prototype.toString.call(value) === '[object Date]') { + this.data[row][col].v = tool.jd2ed(value) + this.data[row][col].t = 'n'; + return value + } + } + throw new TypeError(); }; Sheet.prototype.merge = function(from_cell, to_cell) { @@ -356,6 +389,10 @@ Sheet = (function() { return this.row_ht[row] = ht; }; + Sheet.prototype.format = function(col, row, frmt_s) { + return this.styles['frmt_' + col + '_' + row] = this.book.st.frmt2id(frmt_s); + }; + Sheet.prototype.font = function(col, row, font_s) { return this.styles['font_' + col + '_' + row] = this.book.st.font2id(font_s); }; @@ -388,6 +425,7 @@ Sheet = (function() { var id, inx, style; inx = '_' + col + '_' + row; style = { + frmt_id: this.styles['frmt' + inx], font_id: this.styles['font' + inx], fill_id: this.styles['fill' + inx], bder_id: this.styles['bder' + inx], @@ -445,14 +483,20 @@ Sheet = (function() { for (j = 1, _ref3 = this.cols; 1 <= _ref3 ? j <= _ref3 : j >= _ref3; 1 <= _ref3 ? j++ : j--) { ix = this.data[i][j]; sid = this.style_id(j, i); - if ((ix.v !== 0) || (sid !== 1)) { + if ((ix.v !== null) || (sid !== 1)) { c = r.ele('c', { r: '' + tool.i2a(j) + i }); if (sid !== 1) c.att('s', '' + (sid - 1)); - if (ix.v !== 0) { - c.att('t', 's'); - c.ele('v', '' + (ix.v - 1)); + if (ix.v !== null) { + if (ix.t === 's') { + c.att('t', 's'); + c.ele('v', '' + (ix.v - 1)); + } else if (ix.t === 'n') { + c.ele('v', '' + ix.v); + } else { + c.ele('v', ''); + } } } } @@ -499,6 +543,7 @@ Style = (function() { function Style(book) { this.book = book; this.cache = {}; + this.mfrmts = []; this.mfonts = []; this.mfills = []; this.mbders = []; @@ -507,6 +552,7 @@ Style = (function() { } Style.prototype.with_default = function() { + this.def_frmt_id = this.frmt2id(null); this.def_font_id = this.font2id(null); this.def_fill_id = this.fill2id(null); this.def_bder_id = this.bder2id(null); @@ -515,6 +561,7 @@ Style = (function() { this.def_rotate = '-'; this.def_wrap = '-'; return this.def_style_id = this.style2id({ + frmt_id: this.def_frmt_id, font_id: this.def_font_id, fill_id: this.def_fill_id, bder_id: this.def_bder_id, @@ -524,6 +571,20 @@ Style = (function() { }); }; + Style.prototype.frmt2id = function(frmt) { + var id, k; + frmt || (frmt = '-'); + k = 'frmt_' + frmt; + id = this.cache[k]; + if (id) { + return id; + } else { + this.mfrmts.push(frmt); + this.cache[k] = this.mfrmts.length + (this.mfrmts.length > 1 ? 165 : 0); + return this.cache[k]; + } + }; + Style.prototype.font2id = function(font) { var id, k; font || (font = {}); @@ -586,10 +647,13 @@ Style = (function() { style.valign || (style.valign = this.def_valign); style.rotate || (style.rotate = this.def_rotate); style.wrap || (style.wrap = this.def_wrap); + style.frmt_id || (style.frmt_id = this.def_frmt_id); style.font_id || (style.font_id = this.def_font_id); style.fill_id || (style.fill_id = this.def_fill_id); style.bder_id || (style.bder_id = this.def_bder_id); - k = 's_' + style.font_id + '_' + style.fill_id + '_' + style.bder_id + '_' + style.align + '_' + style.valign + '_' + style.wrap + '_' + style.rotate; + k = 's_' + + style.frmt_id + '_' + style.font_id + '_' + style.fill_id + '_' + style.bder_id + '_' + + style.align + '_' + style.valign + '_' + style.wrap + '_' + style.rotate; id = this.cache[k]; if (id) { return id; @@ -601,13 +665,24 @@ Style = (function() { }; Style.prototype.toxml = function() { - var bders, cs, e, ea, es, fills, fonts, o, ss, _i, _j, _k, _l, _len, _len2, _len3, _len4, _ref, _ref2, _ref3, _ref4; + var bders, cs, e, ea, es, fills, frmts, fonts, o, ss, _i, _j, _k, _l, _len, _len2, _len3, _len4, _ref, _ref2, _ref3, _ref4; ss = xml.create('styleSheet', { version: '1.0', encoding: 'UTF-8', standalone: true }); ss.att('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + frmts = ss.ele('numFmts', { + count: this.mfrmts.length - 1 + }); + _ref = this.mfrmts; + for (_i = 1, _len = _ref.length; _i < _len; _i++) { + o = _ref[_i]; + frmts.ele('numFmt', { + numFmtId: this.frmt2id(o) - 1, + formatCode: o + }); + } fonts = ss.ele('fonts', { count: this.mfonts.length }); @@ -724,12 +799,13 @@ Style = (function() { for (_l = 0, _len4 = _ref4.length; _l < _len4; _l++) { o = _ref4[_l]; e = cs.ele('xf', { - numFmtId: '0', + numFmtId: o.frmt_id - 1, fontId: o.font_id - 1, fillId: o.fill_id - 1, borderId: o.bder_id - 1, xfId: '0' }); + if (o.frmt_id !== 1) e.att('applyNumberFormat', '1'); if (o.font_id !== 1) e.att('applyFont', '1'); if (o.fill_id !== 1) e.att('applyFill', '1'); if (o.bder_id !== 1) e.att('applyBorder', '1');