forked from sheetjs/sheetjs
RTF write stub
- Empty WS on RTF read, rudimentary write - reshape XLS VBA blob - CI adding back old nodejs versions - refresh tests and docs
This commit is contained in:
parent
af3df44633
commit
c88f83940c
1
.gitignore
vendored
1
.gitignore
vendored
@ -21,6 +21,7 @@ tmp
|
||||
*.[wW][kKqQbB][S1234567890]
|
||||
*.[qQ][pP][wW]
|
||||
*.[bB][iI][fF][fF][23458]
|
||||
*.[rR][tT][fF]
|
||||
*.123
|
||||
*.htm
|
||||
*.html
|
||||
|
@ -23,6 +23,7 @@ tmp
|
||||
*.[wW][kKqQbB][S1234567890]
|
||||
*.[qQ][pP][wW]
|
||||
*.[bB][iI][fF][fF][23458]
|
||||
*.[rR][tT][fF]
|
||||
*.123
|
||||
*.htm
|
||||
*.html
|
||||
@ -30,6 +31,7 @@ tmp
|
||||
*.exe
|
||||
.gitignore
|
||||
.fossaignore
|
||||
.spelling
|
||||
.eslintrc
|
||||
.jshintrc
|
||||
CONTRIBUTING.md
|
||||
|
@ -18,10 +18,15 @@ PivotTable
|
||||
Quattro
|
||||
SpreadsheetML
|
||||
Unhide
|
||||
VBA
|
||||
Visicalc
|
||||
chartsheet
|
||||
chartsheets
|
||||
dialogsheet
|
||||
dialogsheets
|
||||
dBASE
|
||||
macrosheet
|
||||
macrosheets
|
||||
tooltip
|
||||
tooltips
|
||||
|
||||
|
19
.travis.yml
19
.travis.yml
@ -3,13 +3,6 @@ node_js:
|
||||
- "8"
|
||||
- "7"
|
||||
- "6"
|
||||
# note: travis has been acting up on old versions of node
|
||||
# - "5"
|
||||
# - "4"
|
||||
# - "0.12"
|
||||
# - "0.10"
|
||||
# - "0.9"
|
||||
# - "0.8"
|
||||
matrix:
|
||||
include:
|
||||
- node_js: "6"
|
||||
@ -26,6 +19,18 @@ matrix:
|
||||
env: TZ="Asia/Shanghai"
|
||||
- node_js: "8"
|
||||
env: TZ="Asia/Seoul" FMTS=misc
|
||||
|
||||
- node_js: "5"
|
||||
env: TZ="America/Anchorage" FMTS=misc
|
||||
- node_js: "4"
|
||||
env: TZ="America/Barbados" FMTS=misc
|
||||
- node_js: "0.12"
|
||||
env: TZ="America/Cayman" FMTS=misc
|
||||
- node_js: "0.10"
|
||||
env: TZ="Pacific/Honolulu" FMTS=misc
|
||||
- node_js: "0.8"
|
||||
env: TZ="America/Mexico_City" FMTS=misc
|
||||
|
||||
before_install:
|
||||
- "npm install -g npm@4.3.0"
|
||||
- "npm install -g mocha@2.x voc"
|
||||
|
63
README.md
63
README.md
@ -78,6 +78,8 @@ enhancements, additional features by request, and dedicated support.
|
||||
* [Sheet Objects](#sheet-objects)
|
||||
+ [Worksheet Object](#worksheet-object)
|
||||
+ [Chartsheet Object](#chartsheet-object)
|
||||
+ [Macrosheet Object](#macrosheet-object)
|
||||
+ [Dialogsheet Object](#dialogsheet-object)
|
||||
* [Workbook Object](#workbook-object)
|
||||
+ [Workbook File Properties](#workbook-file-properties)
|
||||
* [Workbook-Level Attributes](#workbook-level-attributes)
|
||||
@ -91,6 +93,7 @@ enhancements, additional features by request, and dedicated support.
|
||||
+ [Hyperlinks](#hyperlinks)
|
||||
+ [Cell Comments](#cell-comments)
|
||||
+ [Sheet Visibility](#sheet-visibility)
|
||||
+ [VBA and Macros](#vba-and-macros)
|
||||
- [Parsing Options](#parsing-options)
|
||||
* [Input Type](#input-type)
|
||||
* [Guessing File Type](#guessing-file-type)
|
||||
@ -124,6 +127,7 @@ enhancements, additional features by request, and dedicated support.
|
||||
+ [Lotus Formatted Text (PRN)](#lotus-formatted-text-prn)
|
||||
+ [Data Interchange Format (DIF)](#data-interchange-format-dif)
|
||||
+ [HTML](#html)
|
||||
+ [Rich Text Format (RTF)](#rich-text-format-rtf)
|
||||
- [Testing](#testing)
|
||||
* [Node](#node)
|
||||
* [Browser](#browser)
|
||||
@ -983,6 +987,16 @@ Chartsheets are represented as standard sheets. They are distinguished with the
|
||||
The underlying data and `!ref` refer to the cached data in the chartsheet. The
|
||||
first row of the chartsheet is the underlying header.
|
||||
|
||||
#### Macrosheet Object
|
||||
|
||||
Macrosheets are represented as standard sheets. They are distinguished with the
|
||||
`!type` property set to `"macro"`.
|
||||
|
||||
#### Dialogsheet Object
|
||||
|
||||
Dialogsheets are represented as standard sheets. They are distinguished with the
|
||||
`!type` property set to `"dialog"`.
|
||||
|
||||
### Workbook Object
|
||||
|
||||
`workbook.SheetNames` is an ordered list of the sheets in the workbook
|
||||
@ -1421,6 +1435,37 @@ if a sheet is visible is to check if the `Hidden` property is logical truth:
|
||||
```
|
||||
</details>
|
||||
|
||||
#### VBA and Macros
|
||||
|
||||
VBA Macros are stored in a special data blob that is exposed in the `vbaraw`
|
||||
property of the workbook object when the `bookVBA` option is `true`. They are
|
||||
supported in `XLSM`, `XLSB`, and `BIFF8 XLS` formats. The `XLSM` and `XLSB`
|
||||
writers automatically insert the data blobs if it is present in the workbook.
|
||||
|
||||
<details>
|
||||
<summary><b>Macrosheets</b> (click to show)</summary>
|
||||
|
||||
Older versions of Excel also supported a non-VBA "macrosheet" sheet type that
|
||||
stored automation commands. These are exposed in objects with the `!type`
|
||||
property set to `"macro"`.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Detecting macros in workbooks</b> (click to show)</summary>
|
||||
|
||||
The `vbaraw` field will only be set if macros are present, so testing is simple:
|
||||
|
||||
```js
|
||||
function wb_has_macro(wb/*:workbook*/)/*:boolean*/ {
|
||||
if(!!wb.vbaraw) return true;
|
||||
const sheets = wb.SheetNames.map((n) => wb.Sheets[n]);
|
||||
return sheets.some((ws) => !!ws && ws['!type']=='macro');
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Parsing Options
|
||||
|
||||
The exported `read` and `readFile` functions accept an options argument:
|
||||
@ -1459,7 +1504,9 @@ The exported `read` and `readFile` functions accept an options argument:
|
||||
- `sheetRows-1` rows will be generated when looking at the JSON object output
|
||||
(since the header row is counted as a row when parsing the data)
|
||||
- `bookVBA` merely exposes the raw VBA CFB object. It does not parse the data.
|
||||
XLSM and XLSB store the VBA CFB object in `xl/vbaProject.bin`.
|
||||
XLSM and XLSB store the VBA CFB object in `xl/vbaProject.bin`. BIFF8 XLS mixes
|
||||
the VBA entries alongside the core Workbook entry, so the library generates a
|
||||
new XLSB-compatible blob from the XLS CFB container.
|
||||
- Currently only XOR encryption is supported. Unsupported error will be thrown
|
||||
for files employing other encryption methods.
|
||||
- WTF is mainly for development. By default, the parser will suppress read
|
||||
@ -1591,6 +1638,7 @@ output formats. The specific file type is controlled with `bookType` option:
|
||||
| `sylk` | `.sylk` | none | single | Symbolic Link (SYLK) |
|
||||
| `html` | `.html` | none | single | HTML Document |
|
||||
| `dif` | `.dif` | none | single | Data Interchange Format (DIF) |
|
||||
| `rtf` | `.rtf` | none | single | Rich Text Format |
|
||||
| `prn` | `.prn` | none | single | Lotus Formatted Text |
|
||||
|
||||
- `compression` only applies to formats with ZIP containers.
|
||||
@ -1928,6 +1976,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Quattro Pro Spreadsheet (WQ1/WQ2/WB1/WB2/WB3/QPW) | :o: | |
|
||||
| **Other Common Spreadsheet Output Formats** |:-----:|:-----:|
|
||||
| HTML Tables | :o: | :o: |
|
||||
| RTF Tables | | :o: |
|
||||
|
||||
### Excel 2007+ XML (XLSX/XLSM)
|
||||
|
||||
@ -2151,6 +2200,17 @@ the metadata the output is valid HTML, although it does accept bare `&` symbols.
|
||||
|
||||
</details>
|
||||
|
||||
#### Rich Text Format (RTF)
|
||||
|
||||
<details>
|
||||
<summary>(click to show)</summary>
|
||||
|
||||
Excel RTF worksheets are stored in clipboard when copying cells or ranges from a
|
||||
worksheet. The supported codes are a subset of the Word RTF support.
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
## Testing
|
||||
|
||||
### Node
|
||||
@ -2394,6 +2454,7 @@ granted by the Apache 2.0 License are reserved by the Original Author.
|
||||
- `MS-XLSB`: Excel (.xlsb) Binary File Format
|
||||
- `MS-XLSX`: Excel (.xlsx) Extensions to the Office Open XML SpreadsheetML File Format
|
||||
- `XLS`: Microsoft Office Excel 97-2007 Binary File Format Specification
|
||||
- `RTF`: Rich Text Format
|
||||
|
||||
</details>
|
||||
|
||||
|
26
bin/xlsx.njs
26
bin/xlsx.njs
@ -28,15 +28,16 @@ program
|
||||
.option('-6, --xlml', 'emit SSML to <sheetname> or <file>.xls (2003 XML)')
|
||||
.option('-T, --fods', 'emit FODS to <sheetname> or <file>.fods (Flat ODS)')
|
||||
|
||||
.option('-S, --formulae', 'print formulae')
|
||||
.option('-j, --json', 'emit formatted JSON (all fields text)')
|
||||
.option('-J, --raw-js', 'emit raw JS object (raw numbers)')
|
||||
.option('-A, --arrays', 'emit rows as JS objects (raw numbers)')
|
||||
.option('-H, --html', 'emit HTML')
|
||||
.option('-D, --dif', 'emit data interchange format (dif)')
|
||||
.option('-K, --sylk', 'emit symbolic link (sylk)')
|
||||
.option('-P, --prn', 'emit formatted text (prn)')
|
||||
.option('-t, --txt', 'emit delimited text (txt)')
|
||||
.option('-S, --formulae', 'emit list of values and formulae')
|
||||
.option('-j, --json', 'emit formatted JSON (all fields text)')
|
||||
.option('-J, --raw-js', 'emit raw JS object (raw numbers)')
|
||||
.option('-A, --arrays', 'emit rows as JS objects (raw numbers)')
|
||||
.option('-H, --html', 'emit HTML to <sheetname> or <file>.html')
|
||||
.option('-D, --dif', 'emit DIF to <sheetname> or <file>.dif (Lotus DIF)')
|
||||
.option('-K, --sylk', 'emit SYLK to <sheetname> or <file>.slk (Excel SYLK)')
|
||||
.option('-P, --prn', 'emit PRN to <sheetname> or <file>.prn (Lotus PRN)')
|
||||
.option('-t, --txt', 'emit TXT to <sheetname> or <file>.txt (UTF-8 TSV)')
|
||||
.option('-r, --rtf', 'emit RTF to <sheetname> or <file>.txt (Table RTF)')
|
||||
|
||||
.option('-F, --field-sep <sep>', 'CSV field separator', ",")
|
||||
.option('-R, --row-sep <sep>', 'CSV row separator', "\n")
|
||||
@ -62,7 +63,7 @@ var workbook_formats = [
|
||||
['xlsm', 'xlsm', 'xlsm'],
|
||||
['xlsb', 'xlsb', 'xlsb'],
|
||||
['xls', 'xls', 'xls'],
|
||||
//['biff5', 'biff5', 'xls'],
|
||||
['biff5', 'biff5', 'xls'],
|
||||
['ods', 'ods', 'ods'],
|
||||
['fods', 'fods', 'fods']
|
||||
];
|
||||
@ -180,11 +181,12 @@ if(program.readOnly) process.exit(0);
|
||||
/* single worksheet formats */
|
||||
[
|
||||
['biff2', '.xls'],
|
||||
//['biff3', '.xls'],
|
||||
//['biff4', '.xls'],
|
||||
['biff3', '.xls'],
|
||||
['biff4', '.xls'],
|
||||
['sylk', '.slk'],
|
||||
['html', '.html'],
|
||||
['prn', '.prn'],
|
||||
['rtf', '.rtf'],
|
||||
['txt', '.txt'],
|
||||
['dif', '.dif']
|
||||
].forEach(function(m) { if(program[m[0]] || isfmt(m[1])) {
|
||||
|
@ -27,7 +27,7 @@ function write_double_le(b/*:RawBytes|CFBlob*/, v/*:number*/, idx/*:number*/) {
|
||||
|
||||
var __toBuffer = function(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
|
||||
var ___toBuffer = __toBuffer;
|
||||
var __utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/)/*:string*/ { var ss/*:Array<string>*/=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join(""); };
|
||||
var __utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/)/*:string*/ { var ss/*:Array<string>*/=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join("").replace(chr0,''); };
|
||||
var ___utf16le = __utf16le;
|
||||
var __hexlify = function(b/*:RawBytes|CFBlob*/,s/*:number*/,l/*:number*/)/*:string*/ { var ss/*:Array<string>*/=[]; for(var i=s; i<s+l; ++i) ss.push(("0" + b[i].toString(16)).slice(-2)); return ss.join(""); };
|
||||
var ___hexlify = __hexlify;
|
||||
@ -46,7 +46,7 @@ __double = ___double = function(b/*:RawBytes|CFBlob*/, idx/*:number*/) { return
|
||||
var is_buf = function is_buf_a(a) { return Array.isArray(a); };
|
||||
|
||||
if(has_buf/*:: && typeof Buffer !== 'undefined'*/) {
|
||||
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/)/*:string*/ { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___utf16le(b,s,e); return b.toString('utf16le',s,e); };
|
||||
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/)/*:string*/ { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___utf16le(b,s,e); return b.toString('utf16le',s,e).replace(chr0,'')/*.replace(chr1,'!')*/; };
|
||||
__hexlify = function(b/*:RawBytes|CFBlob*/,s/*:number*/,l/*:number*/)/*:string*/ { return Buffer.isBuffer(b)/*:: && b instanceof Buffer*/ ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); };
|
||||
__lpstr = function lpstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
|
||||
__lpwstr = function lpwstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpwstr(b, i); var len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};
|
||||
@ -61,7 +61,7 @@ if(has_buf/*:: && typeof Buffer !== 'undefined'*/) {
|
||||
|
||||
/* from js-xls */
|
||||
if(typeof cptable !== 'undefined') {
|
||||
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(1200, b.slice(s,e)); };
|
||||
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(1200, b.slice(s,e)).replace(chr0, ''); };
|
||||
__utf8 = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(65001, b.slice(s,e)); };
|
||||
__lpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(current_codepage, b.slice(i+4, i+4+len-1)) : "";};
|
||||
__lpwstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = 2*__readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len-1)) : "";};
|
||||
|
@ -10,11 +10,39 @@ var RTF = (function() {
|
||||
}
|
||||
|
||||
function rtf_to_sheet_str(str/*:string*/, opts)/*:Worksheet*/ {
|
||||
throw new Error("Unsupported RTF");
|
||||
var o = opts || {};
|
||||
var ws/*:Worksheet*/ = ({}/*:any*/);
|
||||
var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:0, r:0}}/*:any*/);
|
||||
|
||||
// TODO: parse
|
||||
if(!str.match(/\\trowd/)) throw new Error("RTF missing table");
|
||||
|
||||
ws['!ref'] = encode_range(range);
|
||||
return ws;
|
||||
}
|
||||
|
||||
function rtf_to_workbook(d/*:RawData*/, opts)/*:Workbook*/ { return sheet_to_workbook(rtf_to_sheet(d, opts), opts); }
|
||||
function sheet_to_rtf() { throw new Error("Unsupported"); }
|
||||
|
||||
/* TODO: this is a stub */
|
||||
function sheet_to_rtf(ws/*:Worksheet*/, opts)/*:string*/ {
|
||||
var o = ["{\\rtf1\\ansi"];
|
||||
var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
|
||||
var dense = Array.isArray(ws);
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) {
|
||||
o.push("\\trowd\\trautofit1");
|
||||
for(var C = r.s.c; C <= r.e.c; ++C) o.push("\\cellx" + (C+1));
|
||||
o.push("\\pard\\intbl");
|
||||
for(C = r.s.c; C <= r.e.c; ++C) {
|
||||
var coord = encode_cell({r:R,c:C});
|
||||
cell = dense ? (ws[R]||[])[C]: ws[coord];
|
||||
if(!cell || cell.v == null && (!cell.f || cell.F)) continue;
|
||||
o.push(" " + (cell.w || (format_cell(cell), cell.w)));
|
||||
o.push("\\cell");
|
||||
}
|
||||
o.push("\\pard\\intbl\\row");
|
||||
}
|
||||
return o.join("") + "}";
|
||||
}
|
||||
|
||||
return {
|
||||
to_workbook: rtf_to_workbook,
|
||||
|
9
bits/59_vba.js
Normal file
9
bits/59_vba.js
Normal file
@ -0,0 +1,9 @@
|
||||
function make_vba_xls(cfb/*:CFBContainer*/) {
|
||||
var newcfb = CFB.utils.cfb_new({root:"R"});
|
||||
cfb.FullPaths.forEach(function(p, i) {
|
||||
if(p.slice(-1) === "/" || !p.match(/_VBA_PROJECT_CUR/)) return;
|
||||
var newpath = p.replace(/^[^/]*/,"R").replace(/\/_VBA_PROJECT_CUR\u0000*/, "");
|
||||
CFB.utils.cfb_add(newcfb, newpath, cfb.FileIndex[i].content);
|
||||
});
|
||||
return CFB.write(newcfb);
|
||||
}
|
@ -136,7 +136,8 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
|
||||
|
||||
/* Others */
|
||||
case '<ArchID': break;
|
||||
case '<AlternateContent': pass=true; break;
|
||||
case '<AlternateContent':
|
||||
case '<AlternateContent>': pass=true; break;
|
||||
case '</AlternateContent>': pass=false; break;
|
||||
|
||||
/* TODO */
|
||||
|
@ -868,6 +868,7 @@ else/*:: if(cfb instanceof CFBContainer) */ {
|
||||
/* Quattro Pro 9 */
|
||||
else if((_data=CFB.find(cfb, 'NativeContent_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
|
||||
else throw new Error("Cannot find Workbook stream");
|
||||
if(options.bookVBA && CFB.find(cfb, '/_VBA_PROJECT_CUR/VBA/dir')) WorkbookP.vbaraw = make_vba_xls(cfb);
|
||||
}
|
||||
|
||||
var props = {};
|
||||
|
@ -60,3 +60,13 @@ Chartsheets are represented as standard sheets. They are distinguished with the
|
||||
The underlying data and `!ref` refer to the cached data in the chartsheet. The
|
||||
first row of the chartsheet is the underlying header.
|
||||
|
||||
#### Macrosheet Object
|
||||
|
||||
Macrosheets are represented as standard sheets. They are distinguished with the
|
||||
`!type` property set to `"macro"`.
|
||||
|
||||
#### Dialogsheet Object
|
||||
|
||||
Dialogsheets are represented as standard sheets. They are distinguished with the
|
||||
`!type` property set to `"dialog"`.
|
||||
|
||||
|
31
docbits/77_macrovba.md
Normal file
31
docbits/77_macrovba.md
Normal file
@ -0,0 +1,31 @@
|
||||
#### VBA and Macros
|
||||
|
||||
VBA Macros are stored in a special data blob that is exposed in the `vbaraw`
|
||||
property of the workbook object when the `bookVBA` option is `true`. They are
|
||||
supported in `XLSM`, `XLSB`, and `BIFF8 XLS` formats. The `XLSM` and `XLSB`
|
||||
writers automatically insert the data blobs if it is present in the workbook.
|
||||
|
||||
<details>
|
||||
<summary><b>Macrosheets</b> (click to show)</summary>
|
||||
|
||||
Older versions of Excel also supported a non-VBA "macrosheet" sheet type that
|
||||
stored automation commands. These are exposed in objects with the `!type`
|
||||
property set to `"macro"`.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Detecting macros in workbooks</b> (click to show)</summary>
|
||||
|
||||
The `vbaraw` field will only be set if macros are present, so testing is simple:
|
||||
|
||||
```js
|
||||
function wb_has_macro(wb/*:workbook*/)/*:boolean*/ {
|
||||
if(!!wb.vbaraw) return true;
|
||||
const sheets = wb.SheetNames.map((n) => wb.Sheets[n]);
|
||||
return sheets.some((ws) => !!ws && ws['!type']=='macro');
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
@ -36,7 +36,9 @@ The exported `read` and `readFile` functions accept an options argument:
|
||||
- `sheetRows-1` rows will be generated when looking at the JSON object output
|
||||
(since the header row is counted as a row when parsing the data)
|
||||
- `bookVBA` merely exposes the raw VBA CFB object. It does not parse the data.
|
||||
XLSM and XLSB store the VBA CFB object in `xl/vbaProject.bin`.
|
||||
XLSM and XLSB store the VBA CFB object in `xl/vbaProject.bin`. BIFF8 XLS mixes
|
||||
the VBA entries alongside the core Workbook entry, so the library generates a
|
||||
new XLSB-compatible blob from the XLS CFB container.
|
||||
- Currently only XOR encryption is supported. Unsupported error will be thrown
|
||||
for files employing other encryption methods.
|
||||
- WTF is mainly for development. By default, the parser will suppress read
|
||||
|
@ -45,6 +45,7 @@ output formats. The specific file type is controlled with `bookType` option:
|
||||
| `sylk` | `.sylk` | none | single | Symbolic Link (SYLK) |
|
||||
| `html` | `.html` | none | single | HTML Document |
|
||||
| `dif` | `.dif` | none | single | Data Interchange Format (DIF) |
|
||||
| `rtf` | `.rtf` | none | single | Rich Text Format |
|
||||
| `prn` | `.prn` | none | single | Lotus Formatted Text |
|
||||
|
||||
- `compression` only applies to formats with ZIP containers.
|
||||
|
@ -28,6 +28,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Quattro Pro Spreadsheet (WQ1/WQ2/WB1/WB2/WB3/QPW) | :o: | |
|
||||
| **Other Common Spreadsheet Output Formats** |:-----:|:-----:|
|
||||
| HTML Tables | :o: | :o: |
|
||||
| RTF Tables | | :o: |
|
||||
|
||||
### Excel 2007+ XML (XLSX/XLSM)
|
||||
|
||||
@ -251,3 +252,14 @@ the metadata the output is valid HTML, although it does accept bare `&` symbols.
|
||||
|
||||
</details>
|
||||
|
||||
#### Rich Text Format (RTF)
|
||||
|
||||
<details>
|
||||
<summary>(click to show)</summary>
|
||||
|
||||
Excel RTF worksheets are stored in clipboard when copying cells or ranges from a
|
||||
worksheet. The supported codes are a subset of the Word RTF support.
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
- `MS-XLSB`: Excel (.xlsb) Binary File Format
|
||||
- `MS-XLSX`: Excel (.xlsx) Extensions to the Office Open XML SpreadsheetML File Format
|
||||
- `XLS`: Microsoft Office Excel 97-2007 Binary File Format Specification
|
||||
- `RTF`: Rich Text Format
|
||||
|
||||
</details>
|
||||
|
||||
|
@ -25,6 +25,7 @@ digraph G {
|
||||
dif [label="DIF"];
|
||||
slk [label="SYLK"];
|
||||
prn [label="PRN"];
|
||||
rtf [label="RTF"];
|
||||
wk1 [label="WK1/2\n123"];
|
||||
wk3 [label="WK3/4"];
|
||||
wqb [label="WQ*\nWB*"];
|
||||
@ -62,6 +63,7 @@ digraph G {
|
||||
wk1 -> csf
|
||||
wqb -> csf
|
||||
dif -> csf
|
||||
csf -> rtf
|
||||
prn -> csf
|
||||
csf -> prn
|
||||
csv -> csf
|
||||
|
BIN
formats.png
BIN
formats.png
Binary file not shown.
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 179 KiB |
@ -73,6 +73,8 @@ enhancements, additional features by request, and dedicated support.
|
||||
* [Sheet Objects](#sheet-objects)
|
||||
+ [Worksheet Object](#worksheet-object)
|
||||
+ [Chartsheet Object](#chartsheet-object)
|
||||
+ [Macrosheet Object](#macrosheet-object)
|
||||
+ [Dialogsheet Object](#dialogsheet-object)
|
||||
* [Workbook Object](#workbook-object)
|
||||
+ [Workbook File Properties](#workbook-file-properties)
|
||||
* [Workbook-Level Attributes](#workbook-level-attributes)
|
||||
@ -86,6 +88,7 @@ enhancements, additional features by request, and dedicated support.
|
||||
+ [Hyperlinks](#hyperlinks)
|
||||
+ [Cell Comments](#cell-comments)
|
||||
+ [Sheet Visibility](#sheet-visibility)
|
||||
+ [VBA and Macros](#vba-and-macros)
|
||||
- [Parsing Options](#parsing-options)
|
||||
* [Input Type](#input-type)
|
||||
* [Guessing File Type](#guessing-file-type)
|
||||
@ -119,6 +122,7 @@ enhancements, additional features by request, and dedicated support.
|
||||
+ [Lotus Formatted Text (PRN)](#lotus-formatted-text-prn)
|
||||
+ [Data Interchange Format (DIF)](#data-interchange-format-dif)
|
||||
+ [HTML](#html)
|
||||
+ [Rich Text Format (RTF)](#rich-text-format-rtf)
|
||||
- [Testing](#testing)
|
||||
* [Node](#node)
|
||||
* [Browser](#browser)
|
||||
@ -902,6 +906,16 @@ Chartsheets are represented as standard sheets. They are distinguished with the
|
||||
The underlying data and `!ref` refer to the cached data in the chartsheet. The
|
||||
first row of the chartsheet is the underlying header.
|
||||
|
||||
#### Macrosheet Object
|
||||
|
||||
Macrosheets are represented as standard sheets. They are distinguished with the
|
||||
`!type` property set to `"macro"`.
|
||||
|
||||
#### Dialogsheet Object
|
||||
|
||||
Dialogsheets are represented as standard sheets. They are distinguished with the
|
||||
`!type` property set to `"dialog"`.
|
||||
|
||||
### Workbook Object
|
||||
|
||||
`workbook.SheetNames` is an ordered list of the sheets in the workbook
|
||||
@ -1301,6 +1315,31 @@ if a sheet is visible is to check if the `Hidden` property is logical truth:
|
||||
[ [ 'Visible', true ], [ 'Hidden', false ], [ 'VeryHidden', false ] ]
|
||||
```
|
||||
|
||||
#### VBA and Macros
|
||||
|
||||
VBA Macros are stored in a special data blob that is exposed in the `vbaraw`
|
||||
property of the workbook object when the `bookVBA` option is `true`. They are
|
||||
supported in `XLSM`, `XLSB`, and `BIFF8 XLS` formats. The `XLSM` and `XLSB`
|
||||
writers automatically insert the data blobs if it is present in the workbook.
|
||||
|
||||
|
||||
Older versions of Excel also supported a non-VBA "macrosheet" sheet type that
|
||||
stored automation commands. These are exposed in objects with the `!type`
|
||||
property set to `"macro"`.
|
||||
|
||||
|
||||
|
||||
The `vbaraw` field will only be set if macros are present, so testing is simple:
|
||||
|
||||
```js
|
||||
function wb_has_macro(wb/*:workbook*/)/*:boolean*/ {
|
||||
if(!!wb.vbaraw) return true;
|
||||
const sheets = wb.SheetNames.map((n) => wb.Sheets[n]);
|
||||
return sheets.some((ws) => !!ws && ws['!type']=='macro');
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Parsing Options
|
||||
|
||||
The exported `read` and `readFile` functions accept an options argument:
|
||||
@ -1339,7 +1378,9 @@ The exported `read` and `readFile` functions accept an options argument:
|
||||
- `sheetRows-1` rows will be generated when looking at the JSON object output
|
||||
(since the header row is counted as a row when parsing the data)
|
||||
- `bookVBA` merely exposes the raw VBA CFB object. It does not parse the data.
|
||||
XLSM and XLSB store the VBA CFB object in `xl/vbaProject.bin`.
|
||||
XLSM and XLSB store the VBA CFB object in `xl/vbaProject.bin`. BIFF8 XLS mixes
|
||||
the VBA entries alongside the core Workbook entry, so the library generates a
|
||||
new XLSB-compatible blob from the XLS CFB container.
|
||||
- Currently only XOR encryption is supported. Unsupported error will be thrown
|
||||
for files employing other encryption methods.
|
||||
- WTF is mainly for development. By default, the parser will suppress read
|
||||
@ -1465,6 +1506,7 @@ output formats. The specific file type is controlled with `bookType` option:
|
||||
| `sylk` | `.sylk` | none | single | Symbolic Link (SYLK) |
|
||||
| `html` | `.html` | none | single | HTML Document |
|
||||
| `dif` | `.dif` | none | single | Data Interchange Format (DIF) |
|
||||
| `rtf` | `.rtf` | none | single | Rich Text Format |
|
||||
| `prn` | `.prn` | none | single | Lotus Formatted Text |
|
||||
|
||||
- `compression` only applies to formats with ZIP containers.
|
||||
@ -1781,6 +1823,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Quattro Pro Spreadsheet (WQ1/WQ2/WB1/WB2/WB3/QPW) | :o: | |
|
||||
| **Other Common Spreadsheet Output Formats** |:-----:|:-----:|
|
||||
| HTML Tables | :o: | :o: |
|
||||
| RTF Tables | | :o: |
|
||||
|
||||
### Excel 2007+ XML (XLSX/XLSM)
|
||||
|
||||
@ -1956,6 +1999,14 @@ Excel HTML worksheets include special metadata encoded in styles. For example,
|
||||
the metadata the output is valid HTML, although it does accept bare `&` symbols.
|
||||
|
||||
|
||||
#### Rich Text Format (RTF)
|
||||
|
||||
|
||||
Excel RTF worksheets are stored in clipboard when copying cells or ranges from a
|
||||
worksheet. The supported codes are a subset of the Word RTF support.
|
||||
|
||||
|
||||
|
||||
## Testing
|
||||
|
||||
### Node
|
||||
@ -2173,6 +2224,7 @@ granted by the Apache 2.0 License are reserved by the Original Author.
|
||||
- `MS-XLSB`: Excel (.xlsb) Binary File Format
|
||||
- `MS-XLSX`: Excel (.xlsx) Extensions to the Office Open XML SpreadsheetML File Format
|
||||
- `XLS`: Microsoft Office Excel 97-2007 Binary File Format Specification
|
||||
- `RTF`: Rich Text Format
|
||||
|
||||
|
||||
- ISO/IEC 29500:2012(E) "Information technology — Document description and processing languages — Office Open XML File Formats"
|
||||
|
@ -26,6 +26,8 @@
|
||||
* [Sheet Objects](README.md#sheet-objects)
|
||||
+ [Worksheet Object](README.md#worksheet-object)
|
||||
+ [Chartsheet Object](README.md#chartsheet-object)
|
||||
+ [Macrosheet Object](README.md#macrosheet-object)
|
||||
+ [Dialogsheet Object](README.md#dialogsheet-object)
|
||||
* [Workbook Object](README.md#workbook-object)
|
||||
+ [Workbook File Properties](README.md#workbook-file-properties)
|
||||
* [Workbook-Level Attributes](README.md#workbook-level-attributes)
|
||||
@ -39,6 +41,7 @@
|
||||
+ [Hyperlinks](README.md#hyperlinks)
|
||||
+ [Cell Comments](README.md#cell-comments)
|
||||
+ [Sheet Visibility](README.md#sheet-visibility)
|
||||
+ [VBA and Macros](README.md#vba-and-macros)
|
||||
- [Parsing Options](README.md#parsing-options)
|
||||
* [Input Type](README.md#input-type)
|
||||
* [Guessing File Type](README.md#guessing-file-type)
|
||||
@ -72,6 +75,7 @@
|
||||
+ [Lotus Formatted Text (PRN)](README.md#lotus-formatted-text-prn)
|
||||
+ [Data Interchange Format (DIF)](README.md#data-interchange-format-dif)
|
||||
+ [HTML](README.md#html)
|
||||
+ [Rich Text Format (RTF)](README.md#rich-text-format-rtf)
|
||||
- [Testing](README.md#testing)
|
||||
* [Node](README.md#node)
|
||||
* [Browser](README.md#browser)
|
||||
|
@ -21,6 +21,7 @@ type Workbook = {
|
||||
|
||||
SSF?: SSFTable;
|
||||
cfb?: any;
|
||||
vbaraw?: any;
|
||||
};
|
||||
|
||||
type WBWBProps = {
|
||||
|
19
test.js
19
test.js
@ -576,12 +576,14 @@ describe('parse options', function() {
|
||||
assert(typeof wb.vbaraw === 'undefined');
|
||||
wb = X.read(fs.readFileSync(paths.nfxlsb), {type:TYPE});
|
||||
assert(typeof wb.vbaraw === 'undefined');
|
||||
wb = X.read(fs.readFileSync(paths.nfxls), {type:TYPE});
|
||||
assert(typeof wb.vbaraw === 'undefined');
|
||||
});
|
||||
it('bookVBA should generate vbaraw (XLSX/XLSB)', function() {
|
||||
var wb = X.read(fs.readFileSync(paths.nfxlsx),{type:TYPE, bookVBA:true});
|
||||
assert(wb.vbaraw);
|
||||
wb = X.read(fs.readFileSync(paths.nfxlsb),{type:TYPE, bookVBA:true});
|
||||
assert(wb.vbaraw);
|
||||
it('bookVBA should generate vbaraw', function() {
|
||||
var wb;
|
||||
wb = X.read(fs.readFileSync(paths.nfxlsx),{type:TYPE, bookVBA:true}); assert(wb.vbaraw);
|
||||
wb = X.read(fs.readFileSync(paths.nfxlsb),{type:TYPE, bookVBA:true}); assert(wb.vbaraw);
|
||||
wb = X.read(fs.readFileSync(paths.nfxls),{type:TYPE, bookVBA:true}); assert(wb.vbaraw);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1068,12 +1070,9 @@ describe('parse features', function() {
|
||||
assert.equal(sheet[3]['てすと'], '2/14/14');
|
||||
});
|
||||
it('cellDates should not affect formatted text', function() {
|
||||
var wb1, ws1, wb2, ws2;
|
||||
var sheetName = 'Sheet1';
|
||||
wb1 = X.read(fs.readFileSync(paths.dtxlsx), {type:TYPE});
|
||||
ws1 = wb1.Sheets[sheetName];
|
||||
wb2 = X.read(fs.readFileSync(paths.dtxlsb), {type:TYPE});
|
||||
ws2 = wb2.Sheets[sheetName];
|
||||
var ws1 = X.read(fs.readFileSync(paths.dtxlsx), {type:TYPE}).Sheets[sheetName];
|
||||
var ws2 = X.read(fs.readFileSync(paths.dtxlsb), {type:TYPE}).Sheets[sheetName];
|
||||
assert.equal(X.utils.sheet_to_csv(ws1),X.utils.sheet_to_csv(ws2));
|
||||
});
|
||||
});
|
||||
|
38
tests.lst
38
tests.lst
@ -12,6 +12,7 @@ apachepoi_hyperlink.xlsb
|
||||
apachepoi_protected_passtika.xlsb.pending
|
||||
apachepoi_sample.xlsb
|
||||
apachepoi_testVarious.xlsb
|
||||
author_snowman.xlsb
|
||||
calendar_stress_test.xlsb.pending
|
||||
cell_style_simple.xlsb
|
||||
column_width.xlsb
|
||||
@ -30,6 +31,7 @@ number_format_entities.xlsb
|
||||
number_format_russian.xlsb
|
||||
numfmt_1_russian.xlsb
|
||||
outline.xlsb
|
||||
page_margins_2016.xlsb
|
||||
phonetic_text.xlsb
|
||||
pivot_table_named_range.xlsb
|
||||
pivot_table_test.xlsb
|
||||
@ -142,6 +144,7 @@ apachepoi_56420.xlsx
|
||||
apachepoi_56502.xlsx
|
||||
apachepoi_56511.xlsx
|
||||
apachepoi_56514.xlsx
|
||||
apachepoi_56557.xlsx
|
||||
apachepoi_56574.xlsx
|
||||
apachepoi_56644.xlsx
|
||||
apachepoi_56688_1.xlsx
|
||||
@ -188,7 +191,13 @@ apachepoi_59746_NoRowNums.xlsx
|
||||
apachepoi_59775.xlsx
|
||||
apachepoi_60255_extra_drawingparts.xlsx
|
||||
apachepoi_60289.xlsx
|
||||
#apachepoi_60384.xlsx
|
||||
apachepoi_60709.xlsx
|
||||
#apachepoi_60825.xlsx # Missing worksheet xml file
|
||||
apachepoi_61034.xlsx
|
||||
apachepoi_61060-conditional-number-formatting.xlsx
|
||||
apachepoi_61063.xlsx
|
||||
apachepoi_61281.xlsx
|
||||
apachepoi_AverageTaxRates.xlsx
|
||||
apachepoi_Booleans.xlsx
|
||||
apachepoi_BrNotClosed.xlsx
|
||||
@ -214,6 +223,7 @@ apachepoi_FormulaSheetRange.xlsx
|
||||
apachepoi_GroupTest.xlsx
|
||||
apachepoi_InlineStrings.xlsx
|
||||
apachepoi_Intersection-52111-xssf.xlsx
|
||||
apachepoi_MatrixFormulaEvalTestData.xlsx
|
||||
apachepoi_NewStyleConditionalFormattings.xlsx
|
||||
apachepoi_NewlineInFormulas.xlsx
|
||||
# apachepoi_NumberFormatApproxTests.xlsx # xlml
|
||||
@ -231,6 +241,7 @@ apachepoi_SimpleWithComments.xlsx
|
||||
apachepoi_StructuredReferences.xlsx
|
||||
apachepoi_StructuredRefs-lots-with-lookups.xlsx
|
||||
# apachepoi_Tables.xlsx # xlml
|
||||
apachepoi_TablesWithDifferentHeaders.xlsx
|
||||
apachepoi_TestShiftRowSharedFormula.xlsx
|
||||
apachepoi_TextFormatTests.xlsx
|
||||
apachepoi_Themes.xlsx
|
||||
@ -254,15 +265,20 @@ apachepoi_atp.xlsx
|
||||
apachepoi_bug60858.xlsx
|
||||
apachepoi_chartTitle_noTitle.xlsx
|
||||
apachepoi_chartTitle_withTitle.xlsx
|
||||
apachepoi_chartTitle_withTitleFormula.xlsx
|
||||
apachepoi_chart_sheet.xlsx
|
||||
apachepoi_commentTest.xlsx
|
||||
apachepoi_comments.xlsx
|
||||
apachepoi_conditional_formatting_with_formula_on_second_sheet.xlsx
|
||||
apachepoi_craftonhills.edu_programreview_report.aspx_goalpriorityreport_0011d159-1eeb-4b63-8833-867b0926e5f3.xlsx
|
||||
apachepoi_customIndexedColors.xlsx
|
||||
apachepoi_dataValidationTableRange.xlsx
|
||||
apachepoi_evaluate_formula_with_structured_table_references.xlsx
|
||||
apachepoi_headerFooterTest.xlsx
|
||||
apachepoi_noSharedStringTable.xlsx
|
||||
apachepoi_picture.xlsx
|
||||
apachepoi_poc-shared-strings.xlsx
|
||||
apachepoi_poc-xmlbomb-empty.xlsx
|
||||
apachepoi_poc-xmlbomb.xlsx
|
||||
# apachepoi_protected_passtika.xlsx # password
|
||||
apachepoi_ref-56737.xlsx
|
||||
@ -275,7 +291,10 @@ apachepoi_sample.xlsx
|
||||
apachepoi_shared_formulas.xlsx
|
||||
apachepoi_sheetProtection_allLocked.xlsx
|
||||
apachepoi_sheetProtection_not_protected.xlsx
|
||||
apachepoi_simple-monthly-budget.xlsx
|
||||
# apachepoi_style-alternate-content.xlsx # bad xml
|
||||
apachepoi_styles.xlsx
|
||||
apachepoi_tableStyle.xlsx
|
||||
apachepoi_template.xlsx
|
||||
apachepoi_unicodeSheetName.xlsx
|
||||
apachepoi_workbookProtection-sheet_password-2013.xlsx
|
||||
@ -287,6 +306,7 @@ apachepoi_workbookProtection_workbook_structure_protected.xlsx
|
||||
apachepoi_workbookProtection_workbook_windows_protected.xlsx
|
||||
apachepoi_workbookProtection_worksheet_protected.xlsx
|
||||
apachepoi_xlsx-jdbc.xlsx
|
||||
author_snowman.xlsx
|
||||
calendar_stress_test.xlsx.pending
|
||||
cell_style_simple.xlsx
|
||||
column_width.xlsx
|
||||
@ -364,6 +384,7 @@ openpyxl_r_nonstandard_workbook_name.xlsx
|
||||
openpyxl_r_null_archive.xlsx.pending
|
||||
openpyxl_r_null_file.xlsx.pending
|
||||
outline.xlsx
|
||||
page_margins_2016.xlsx
|
||||
phonetic_text.xlsx
|
||||
pivot_table_named_range.xlsx
|
||||
rich_text_stress.xlsx
|
||||
@ -422,6 +443,7 @@ spout-xlsx_file_with_no_sheets_in_workbook_xml.xlsx
|
||||
# spout-xlsx_file_with_sheet_xml_not_matching_content_types.xlsx
|
||||
spout-xlsx_one_sheet_with_inline_strings.xlsx
|
||||
spout-xlsx_one_sheet_with_invalid_xml_characters.xlsx
|
||||
spout-xlsx_one_sheet_with_pre_encoded_html_entities.xlsx
|
||||
spout-xlsx_one_sheet_with_shared_multiline_strings.xlsx
|
||||
spout-xlsx_one_sheet_with_shared_strings.xlsx
|
||||
spout-xlsx_one_sheet_with_shared_strings_containing_text_and_hyperlink_in_same_cell.xlsx
|
||||
@ -441,15 +463,18 @@ spout-xlsx_sheet_with_lots_of_shared_strings.xlsx
|
||||
spout-xlsx_sheet_with_missing_cell_reference.xlsx
|
||||
spout-xlsx_sheet_with_no_cells.xlsx
|
||||
spout-xlsx_sheet_with_no_shared_strings_file.xlsx
|
||||
spout-xlsx_sheet_with_prefixed_shared_strings_xml.xlsx
|
||||
spout-xlsx_sheet_with_prefixed_xml_files.xlsx
|
||||
spout-xlsx_sheet_with_preserve_space_shared_strings.xlsx
|
||||
spout-xlsx_sheet_with_pronunciation.xlsx
|
||||
spout-xlsx_sheet_with_row_not_starting_at_column_a.xlsx
|
||||
spout-xlsx_sheet_with_same_numeric_value_date_formatted_differently.xlsx
|
||||
spout-xlsx_sheet_with_untrimmed_inline_strings.xlsx
|
||||
spout-xlsx_sheet_with_zeros_in_row.xlsx
|
||||
spout-xlsx_sheet_without_dimensions_and_empty_cells.xlsx
|
||||
spout-xlsx_sheet_without_dimensions_but_spans_and_empty_cells.xlsx
|
||||
spout-xlsx_two_sheets_with_custom_names.xlsx
|
||||
spout-xlsx_two_sheets_with_custom_names_and_custom_active_tab.xlsx
|
||||
spout-xlsx_two_sheets_with_inline_strings.xlsx
|
||||
spout-xlsx_two_sheets_with_shared_strings.xlsx
|
||||
spout-xlsx_two_sheets_with_sheets_definition_in_reverse_order.xlsx
|
||||
@ -551,7 +576,9 @@ roo_whitespace.xlsm
|
||||
AutoFilter.ods
|
||||
BlankSheetTypes.ods
|
||||
apachepoi_SampleSS.ods
|
||||
author_snowman.ods
|
||||
cell_style_simple.ods
|
||||
comments_stress_test.ods
|
||||
formula_stress_test.ods
|
||||
merge_cells.ods
|
||||
number_format.ods
|
||||
@ -612,6 +639,7 @@ spout-ods_sheet_with_untrimmed_strings.ods
|
||||
spout-ods_sheet_with_various_spaces.ods
|
||||
spout-ods_sheet_with_zeros_in_row.ods
|
||||
spout-ods_two_sheets_with_custom_names.ods
|
||||
spout-ods_two_sheets_with_no_settings_xml_file.ods
|
||||
spout-ods_two_sheets_with_strings.ods
|
||||
sushi.ods
|
||||
biff5/NumberFormatCondition.xls
|
||||
@ -839,6 +867,9 @@ apachepoi_59830.xls
|
||||
apachepoi_59858.xls
|
||||
apachepoi_60273.xls
|
||||
# apachepoi_60284.xls
|
||||
apachepoi_61045_govdocs1_626534.xls
|
||||
apachepoi_61287.xls
|
||||
# apachepoi_61300.xls # node 0.8 oob
|
||||
apachepoi_AbnormalSharedFormulaFlag.xls
|
||||
apachepoi_AreaErrPtg.xls
|
||||
# apachepoi_BOOK_in_capitals.xls # note: worksheet length exceeds 31 chars
|
||||
@ -881,6 +912,7 @@ apachepoi_IrrNpvTestCaseData.xls
|
||||
# apachepoi_LookupFunctionsTestCaseData.xls # xlml
|
||||
apachepoi_MRExtraLines.xls
|
||||
apachepoi_MatchFunctionTestCaseData.xls
|
||||
apachepoi_MatrixFormulaEvalTestData.xls
|
||||
apachepoi_MissingBits.xls
|
||||
apachepoi_NewStyleConditionalFormattings.xls
|
||||
apachepoi_NoGutsRecords.xls
|
||||
@ -942,6 +974,7 @@ apachepoi_WithTwoHyperLinks.xls
|
||||
apachepoi_WrongFormulaRecordType.xls
|
||||
apachepoi_XRefCalc.xls
|
||||
apachepoi_XRefCalcData.xls
|
||||
apachepoi_angelo.edu_content_files_19555-nsse-2011-multiyear-benchmark.xls
|
||||
apachepoi_ar.org.apsme.www_Form%20Inscripcion%20Curso%20NO%20Socios.xls
|
||||
apachepoi_at.gv.land-oberoesterreich.www_cps_rde_xbcr_SID-4A1B954F-5C07F98E_ooe_stat_download_bp10.xls
|
||||
apachepoi_atp.xls
|
||||
@ -974,6 +1007,7 @@ apachepoi_ex47747-sharedFormula.xls
|
||||
apachepoi_excel_with_embeded.xls
|
||||
apachepoi_excelant.xls.pending
|
||||
apachepoi_externalFunctionExample.xls
|
||||
apachepoi_external_image.xls
|
||||
# apachepoi_finance.xls # xlml
|
||||
apachepoi_florida_data.ashx.xls
|
||||
apachepoi_intercept.xls
|
||||
@ -1008,6 +1042,7 @@ apachepoi_text.xls
|
||||
apachepoi_unicodeNameRecord.xls
|
||||
apachepoi_xor-encryption-abc.xls.pending
|
||||
# apachepoi_yearfracExamples.xls # xlml
|
||||
author_snowman.xls
|
||||
calendar_stress_test.xls.pending
|
||||
cell_style_simple.xls
|
||||
column_width.xls
|
||||
@ -1079,6 +1114,7 @@ jxls-examples_chart.xls
|
||||
jxls-examples_colouring.xls
|
||||
jxls-examples_department.xls
|
||||
jxls-examples_dynamiccolumns.xls
|
||||
jxls-examples_dynamicolumns.xls
|
||||
jxls-examples_employees.xls
|
||||
jxls-examples_ex_temp.xls
|
||||
jxls-examples_grouping.xls
|
||||
@ -1202,6 +1238,8 @@ number_format_entities.xls
|
||||
number_format_russian.xls
|
||||
numfmt_1_russian.xls
|
||||
outline.xls
|
||||
page_margins_2016.xls
|
||||
page_margins_2016_5.xls
|
||||
phonetic_text.xls
|
||||
phpexcel_bad_cfb_dir.xls
|
||||
pivot_table_named_range.xls
|
||||
|
@ -576,12 +576,14 @@ describe('parse options', function() {
|
||||
assert(typeof wb.vbaraw === 'undefined');
|
||||
wb = X.read(fs.readFileSync(paths.nfxlsb), {type:TYPE});
|
||||
assert(typeof wb.vbaraw === 'undefined');
|
||||
wb = X.read(fs.readFileSync(paths.nfxls), {type:TYPE});
|
||||
assert(typeof wb.vbaraw === 'undefined');
|
||||
});
|
||||
it('bookVBA should generate vbaraw (XLSX/XLSB)', function() {
|
||||
var wb = X.read(fs.readFileSync(paths.nfxlsx),{type:TYPE, bookVBA:true});
|
||||
assert(wb.vbaraw);
|
||||
wb = X.read(fs.readFileSync(paths.nfxlsb),{type:TYPE, bookVBA:true});
|
||||
assert(wb.vbaraw);
|
||||
var wb;
|
||||
wb = X.read(fs.readFileSync(paths.nfxlsx),{type:TYPE, bookVBA:true}); assert(wb.vbaraw);
|
||||
wb = X.read(fs.readFileSync(paths.nfxlsb),{type:TYPE, bookVBA:true}); assert(wb.vbaraw);
|
||||
wb = X.read(fs.readFileSync(paths.nfxls),{type:TYPE, bookVBA:true}); assert(wb.vbaraw);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1068,12 +1070,9 @@ describe('parse features', function() {
|
||||
assert.equal(sheet[3]['てすと'], '2/14/14');
|
||||
});
|
||||
it('cellDates should not affect formatted text', function() {
|
||||
var wb1, ws1, wb2, ws2;
|
||||
var sheetName = 'Sheet1';
|
||||
wb1 = X.read(fs.readFileSync(paths.dtxlsx), {type:TYPE});
|
||||
ws1 = wb1.Sheets[sheetName];
|
||||
wb2 = X.read(fs.readFileSync(paths.dtxlsb), {type:TYPE});
|
||||
ws2 = wb2.Sheets[sheetName];
|
||||
var ws1 = X.read(fs.readFileSync(paths.dtxlsx), {type:TYPE}).Sheets[sheetName];
|
||||
var ws2 = X.read(fs.readFileSync(paths.dtxlsb), {type:TYPE}).Sheets[sheetName];
|
||||
assert.equal(X.utils.sheet_to_csv(ws1),X.utils.sheet_to_csv(ws2));
|
||||
});
|
||||
});
|
||||
|
@ -172,6 +172,7 @@ var filenames = [
|
||||
['sheetjs.slk'],
|
||||
['sheetjs.htm'],
|
||||
['sheetjs.dif'],
|
||||
['sheetjs.rtf'],
|
||||
['sheetjs.prn']
|
||||
];
|
||||
|
||||
|
@ -20,19 +20,21 @@ program
|
||||
.option('-M, --xlsm', 'emit XLSM to <sheetname> or <file>.xlsm')
|
||||
.option('-X, --xlsx', 'emit XLSX to <sheetname> or <file>.xlsx')
|
||||
.option('-Y, --ods', 'emit ODS to <sheetname> or <file>.ods')
|
||||
.option('-8, --xls', 'emit XLS to <sheetname> or <file>.xls (BIFF8)')
|
||||
.option('-2, --biff2','emit XLS to <sheetname> or <file>.xls (BIFF2)')
|
||||
.option('-6, --xlml', 'emit SSML to <sheetname> or <file>.xls (2003 XML)')
|
||||
.option('-T, --fods', 'emit FODS to <sheetname> or <file>.fods (Flat ODS)')
|
||||
|
||||
.option('-S, --formulae', 'print formulae')
|
||||
.option('-j, --json', 'emit formatted JSON (all fields text)')
|
||||
.option('-J, --raw-js', 'emit raw JS object (raw numbers)')
|
||||
.option('-A, --arrays', 'emit rows as JS objects (raw numbers)')
|
||||
.option('-H, --html', 'emit HTML')
|
||||
.option('-D, --dif', 'emit data interchange format (dif)')
|
||||
.option('-K, --sylk', 'emit symbolic link (sylk)')
|
||||
.option('-P, --prn', 'emit formatted text (prn)')
|
||||
.option('-t, --txt', 'emit delimited text (txt)')
|
||||
.option('-S, --formulae', 'emit list of values and formulae')
|
||||
.option('-j, --json', 'emit formatted JSON (all fields text)')
|
||||
.option('-J, --raw-js', 'emit raw JS object (raw numbers)')
|
||||
.option('-A, --arrays', 'emit rows as JS objects (raw numbers)')
|
||||
.option('-H, --html', 'emit HTML to <sheetname> or <file>.html')
|
||||
.option('-D, --dif', 'emit DIF to <sheetname> or <file>.dif (Lotus DIF)')
|
||||
.option('-K, --sylk', 'emit SYLK to <sheetname> or <file>.slk (Excel SYLK)')
|
||||
.option('-P, --prn', 'emit PRN to <sheetname> or <file>.prn (Lotus PRN)')
|
||||
.option('-t, --txt', 'emit TXT to <sheetname> or <file>.txt (UTF-8 TSV)')
|
||||
.option('-r, --rtf', 'emit RTF to <sheetname> or <file>.txt (Table RTF)')
|
||||
|
||||
.option('-F, --field-sep <sep>', 'CSV field separator', ",")
|
||||
.option('-R, --row-sep <sep>', 'CSV row separator', "\n")
|
||||
@ -52,11 +54,18 @@ program.on('--help', function() {
|
||||
console.log(' Web Demo: http://oss.sheetjs.com/js-'+n+'/');
|
||||
});
|
||||
|
||||
/* output formats, update list with full option name */
|
||||
const workbook_formats = ['xlsx', 'xlsm', 'xlsb', 'ods', 'fods'];
|
||||
/* flag, bookType, default ext */
|
||||
const workbook_formats = [
|
||||
['xlsx', 'xlsx', 'xlsx'],
|
||||
['xlsm', 'xlsm', 'xlsm'],
|
||||
['xlsb', 'xlsb', 'xlsb'],
|
||||
['xls', 'xls', 'xls'],
|
||||
['biff5', 'biff5', 'xls'],
|
||||
['ods', 'ods', 'ods'],
|
||||
['fods', 'fods', 'fods']
|
||||
];
|
||||
const wb_formats_2 = [
|
||||
['xlml', 'xlml', 'xls']
|
||||
['xlml', 'xlml', 'xls']
|
||||
];
|
||||
program.parse(process.argv);
|
||||
|
||||
@ -94,7 +103,7 @@ function isfmt(m: string): boolean {
|
||||
const t = m.charAt(0) === "." ? m : "." + m;
|
||||
return program.output.slice(-t.length) === t;
|
||||
}
|
||||
workbook_formats.forEach(function(m) { if(program[m] || isfmt(m)) { wb_fmt(); } });
|
||||
workbook_formats.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) { wb_fmt(); } });
|
||||
wb_formats_2.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) { wb_fmt(); } });
|
||||
if(seen) {
|
||||
} else if(program.formulae) opts.cellFormula = true;
|
||||
@ -134,8 +143,9 @@ let wopts: X.WritingOptions = ({WTF:opts.WTF, bookSST:program.sst}/*:any*/);
|
||||
if(program.compress) wopts.compression = true;
|
||||
|
||||
/* full workbook formats */
|
||||
workbook_formats.forEach(function(m) { if(program[m] || isfmt(m)) {
|
||||
X.writeFile(wb, program.output || sheetname || ((filename || "") + "." + m), wopts);
|
||||
workbook_formats.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) {
|
||||
wopts.bookType = <X.BookType>(m[1]);
|
||||
X.writeFile(wb, program.output || sheetname || ((filename || "") + "." + m[2]), wopts);
|
||||
process.exit(0);
|
||||
} });
|
||||
|
||||
@ -168,9 +178,12 @@ if(program.readOnly) process.exit(0);
|
||||
/* single worksheet formats */
|
||||
[
|
||||
['biff2', '.xls'],
|
||||
['biff3', '.xls'],
|
||||
['biff4', '.xls'],
|
||||
['sylk', '.slk'],
|
||||
['html', '.html'],
|
||||
['prn', '.prn'],
|
||||
['rtf', '.rtf'],
|
||||
['txt', '.txt'],
|
||||
['dif', '.dif']
|
||||
].forEach(function(m) { if(program[m[0]] || isfmt(m[1])) {
|
||||
|
2
types/index.d.ts
vendored
2
types/index.d.ts
vendored
@ -477,7 +477,7 @@ export type ExcelDataType = 'b' | 'n' | 'e' | 's' | 'd' | 'z';
|
||||
* Type of generated workbook
|
||||
* @default 'xlsx'
|
||||
*/
|
||||
export type BookType = 'xlsx' | 'xlsm' | 'xlsb' | 'xls' | 'biff8' | 'biff2' | 'xlml' | 'ods' | 'fods' | 'csv' | 'txt' | 'sylk' | 'html' | 'dif' | 'prn';
|
||||
export type BookType = 'xlsx' | 'xlsm' | 'xlsb' | 'xls' | 'biff8' | 'biff2' | 'xlml' | 'ods' | 'fods' | 'csv' | 'txt' | 'sylk' | 'html' | 'dif' | 'rtf' | 'prn';
|
||||
|
||||
/** Comment element */
|
||||
export interface Comment {
|
||||
|
51
xlsx.flow.js
51
xlsx.flow.js
@ -2274,7 +2274,7 @@ function write_double_le(b/*:RawBytes|CFBlob*/, v/*:number*/, idx/*:number*/) {
|
||||
|
||||
var __toBuffer = function(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
|
||||
var ___toBuffer = __toBuffer;
|
||||
var __utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/)/*:string*/ { var ss/*:Array<string>*/=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join(""); };
|
||||
var __utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/)/*:string*/ { var ss/*:Array<string>*/=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join("").replace(chr0,''); };
|
||||
var ___utf16le = __utf16le;
|
||||
var __hexlify = function(b/*:RawBytes|CFBlob*/,s/*:number*/,l/*:number*/)/*:string*/ { var ss/*:Array<string>*/=[]; for(var i=s; i<s+l; ++i) ss.push(("0" + b[i].toString(16)).slice(-2)); return ss.join(""); };
|
||||
var ___hexlify = __hexlify;
|
||||
@ -2293,7 +2293,7 @@ __double = ___double = function(b/*:RawBytes|CFBlob*/, idx/*:number*/) { return
|
||||
var is_buf = function is_buf_a(a) { return Array.isArray(a); };
|
||||
|
||||
if(has_buf/*:: && typeof Buffer !== 'undefined'*/) {
|
||||
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/)/*:string*/ { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___utf16le(b,s,e); return b.toString('utf16le',s,e); };
|
||||
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/)/*:string*/ { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___utf16le(b,s,e); return b.toString('utf16le',s,e).replace(chr0,'')/*.replace(chr1,'!')*/; };
|
||||
__hexlify = function(b/*:RawBytes|CFBlob*/,s/*:number*/,l/*:number*/)/*:string*/ { return Buffer.isBuffer(b)/*:: && b instanceof Buffer*/ ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); };
|
||||
__lpstr = function lpstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
|
||||
__lpwstr = function lpwstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpwstr(b, i); var len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};
|
||||
@ -2308,7 +2308,7 @@ if(has_buf/*:: && typeof Buffer !== 'undefined'*/) {
|
||||
|
||||
/* from js-xls */
|
||||
if(typeof cptable !== 'undefined') {
|
||||
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(1200, b.slice(s,e)); };
|
||||
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(1200, b.slice(s,e)).replace(chr0, ''); };
|
||||
__utf8 = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(65001, b.slice(s,e)); };
|
||||
__lpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(current_codepage, b.slice(i+4, i+4+len-1)) : "";};
|
||||
__lpwstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = 2*__readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len-1)) : "";};
|
||||
@ -7030,11 +7030,39 @@ var RTF = (function() {
|
||||
}
|
||||
|
||||
function rtf_to_sheet_str(str/*:string*/, opts)/*:Worksheet*/ {
|
||||
throw new Error("Unsupported RTF");
|
||||
var o = opts || {};
|
||||
var ws/*:Worksheet*/ = ({}/*:any*/);
|
||||
var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:0, r:0}}/*:any*/);
|
||||
|
||||
// TODO: parse
|
||||
if(!str.match(/\\trowd/)) throw new Error("RTF missing table");
|
||||
|
||||
ws['!ref'] = encode_range(range);
|
||||
return ws;
|
||||
}
|
||||
|
||||
function rtf_to_workbook(d/*:RawData*/, opts)/*:Workbook*/ { return sheet_to_workbook(rtf_to_sheet(d, opts), opts); }
|
||||
function sheet_to_rtf() { throw new Error("Unsupported"); }
|
||||
|
||||
/* TODO: this is a stub */
|
||||
function sheet_to_rtf(ws/*:Worksheet*/, opts)/*:string*/ {
|
||||
var o = ["{\\rtf1\\ansi"];
|
||||
var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
|
||||
var dense = Array.isArray(ws);
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) {
|
||||
o.push("\\trowd\\trautofit1");
|
||||
for(var C = r.s.c; C <= r.e.c; ++C) o.push("\\cellx" + (C+1));
|
||||
o.push("\\pard\\intbl");
|
||||
for(C = r.s.c; C <= r.e.c; ++C) {
|
||||
var coord = encode_cell({r:R,c:C});
|
||||
cell = dense ? (ws[R]||[])[C]: ws[coord];
|
||||
if(!cell || cell.v == null && (!cell.f || cell.F)) continue;
|
||||
o.push(" " + (cell.w || (format_cell(cell), cell.w)));
|
||||
o.push("\\cell");
|
||||
}
|
||||
o.push("\\pard\\intbl\\row");
|
||||
}
|
||||
return o.join("") + "}";
|
||||
}
|
||||
|
||||
return {
|
||||
to_workbook: rtf_to_workbook,
|
||||
@ -8673,6 +8701,15 @@ function write_comments_bin(data, opts) {
|
||||
write_record(ba, "BrtEndComments");
|
||||
return ba.end();
|
||||
}
|
||||
function make_vba_xls(cfb/*:CFBContainer*/) {
|
||||
var newcfb = CFB.utils.cfb_new({root:"R"});
|
||||
cfb.FullPaths.forEach(function(p, i) {
|
||||
if(p.slice(-1) === "/" || !p.match(/_VBA_PROJECT_CUR/)) return;
|
||||
var newpath = p.replace(/^[^/]*/,"R").replace(/\/_VBA_PROJECT_CUR\u0000*/, "");
|
||||
CFB.utils.cfb_add(newcfb, newpath, cfb.FileIndex[i].content);
|
||||
});
|
||||
return CFB.write(newcfb);
|
||||
}
|
||||
RELS.DS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/dialogsheet";
|
||||
RELS.MS = "http://schemas.microsoft.com/office/2006/relationships/xlMacrosheet";
|
||||
|
||||
@ -12881,7 +12918,8 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
|
||||
|
||||
/* Others */
|
||||
case '<ArchID': break;
|
||||
case '<AlternateContent': pass=true; break;
|
||||
case '<AlternateContent':
|
||||
case '<AlternateContent>': pass=true; break;
|
||||
case '</AlternateContent>': pass=false; break;
|
||||
|
||||
/* TODO */
|
||||
@ -15291,6 +15329,7 @@ else/*:: if(cfb instanceof CFBContainer) */ {
|
||||
/* Quattro Pro 9 */
|
||||
else if((_data=CFB.find(cfb, 'NativeContent_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
|
||||
else throw new Error("Cannot find Workbook stream");
|
||||
if(options.bookVBA && CFB.find(cfb, '/_VBA_PROJECT_CUR/VBA/dir')) WorkbookP.vbaraw = make_vba_xls(cfb);
|
||||
}
|
||||
|
||||
var props = {};
|
||||
|
51
xlsx.js
51
xlsx.js
@ -2202,7 +2202,7 @@ function write_double_le(b, v, idx) {
|
||||
|
||||
var __toBuffer = function(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
|
||||
var ___toBuffer = __toBuffer;
|
||||
var __utf16le = function(b,s,e) { var ss=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join(""); };
|
||||
var __utf16le = function(b,s,e) { var ss=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join("").replace(chr0,''); };
|
||||
var ___utf16le = __utf16le;
|
||||
var __hexlify = function(b,s,l) { var ss=[]; for(var i=s; i<s+l; ++i) ss.push(("0" + b[i].toString(16)).slice(-2)); return ss.join(""); };
|
||||
var ___hexlify = __hexlify;
|
||||
@ -2221,7 +2221,7 @@ __double = ___double = function(b, idx) { return read_double_le(b, idx);};
|
||||
var is_buf = function is_buf_a(a) { return Array.isArray(a); };
|
||||
|
||||
if(has_buf) {
|
||||
__utf16le = function(b,s,e) { if(!Buffer.isBuffer(b)) return ___utf16le(b,s,e); return b.toString('utf16le',s,e); };
|
||||
__utf16le = function(b,s,e) { if(!Buffer.isBuffer(b)) return ___utf16le(b,s,e); return b.toString('utf16le',s,e).replace(chr0,'')/*.replace(chr1,'!')*/; };
|
||||
__hexlify = function(b,s,l) { return Buffer.isBuffer(b) ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); };
|
||||
__lpstr = function lpstr_b(b, i) { if(!Buffer.isBuffer(b)) return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
|
||||
__lpwstr = function lpwstr_b(b, i) { if(!Buffer.isBuffer(b)) return ___lpwstr(b, i); var len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};
|
||||
@ -2236,7 +2236,7 @@ if(has_buf) {
|
||||
|
||||
/* from js-xls */
|
||||
if(typeof cptable !== 'undefined') {
|
||||
__utf16le = function(b,s,e) { return cptable.utils.decode(1200, b.slice(s,e)); };
|
||||
__utf16le = function(b,s,e) { return cptable.utils.decode(1200, b.slice(s,e)).replace(chr0, ''); };
|
||||
__utf8 = function(b,s,e) { return cptable.utils.decode(65001, b.slice(s,e)); };
|
||||
__lpstr = function(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(current_codepage, b.slice(i+4, i+4+len-1)) : "";};
|
||||
__lpwstr = function(b,i) { var len = 2*__readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len-1)) : "";};
|
||||
@ -6945,11 +6945,39 @@ var RTF = (function() {
|
||||
}
|
||||
|
||||
function rtf_to_sheet_str(str, opts) {
|
||||
throw new Error("Unsupported RTF");
|
||||
var o = opts || {};
|
||||
var ws = ({});
|
||||
var range = ({s: {c:0, r:0}, e: {c:0, r:0}});
|
||||
|
||||
// TODO: parse
|
||||
if(!str.match(/\\trowd/)) throw new Error("RTF missing table");
|
||||
|
||||
ws['!ref'] = encode_range(range);
|
||||
return ws;
|
||||
}
|
||||
|
||||
function rtf_to_workbook(d, opts) { return sheet_to_workbook(rtf_to_sheet(d, opts), opts); }
|
||||
function sheet_to_rtf() { throw new Error("Unsupported"); }
|
||||
|
||||
/* TODO: this is a stub */
|
||||
function sheet_to_rtf(ws, opts) {
|
||||
var o = ["{\\rtf1\\ansi"];
|
||||
var r = safe_decode_range(ws['!ref']), cell;
|
||||
var dense = Array.isArray(ws);
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) {
|
||||
o.push("\\trowd\\trautofit1");
|
||||
for(var C = r.s.c; C <= r.e.c; ++C) o.push("\\cellx" + (C+1));
|
||||
o.push("\\pard\\intbl");
|
||||
for(C = r.s.c; C <= r.e.c; ++C) {
|
||||
var coord = encode_cell({r:R,c:C});
|
||||
cell = dense ? (ws[R]||[])[C]: ws[coord];
|
||||
if(!cell || cell.v == null && (!cell.f || cell.F)) continue;
|
||||
o.push(" " + (cell.w || (format_cell(cell), cell.w)));
|
||||
o.push("\\cell");
|
||||
}
|
||||
o.push("\\pard\\intbl\\row");
|
||||
}
|
||||
return o.join("") + "}";
|
||||
}
|
||||
|
||||
return {
|
||||
to_workbook: rtf_to_workbook,
|
||||
@ -8586,6 +8614,15 @@ function write_comments_bin(data, opts) {
|
||||
write_record(ba, "BrtEndComments");
|
||||
return ba.end();
|
||||
}
|
||||
function make_vba_xls(cfb) {
|
||||
var newcfb = CFB.utils.cfb_new({root:"R"});
|
||||
cfb.FullPaths.forEach(function(p, i) {
|
||||
if(p.slice(-1) === "/" || !p.match(/_VBA_PROJECT_CUR/)) return;
|
||||
var newpath = p.replace(/^[^/]*/,"R").replace(/\/_VBA_PROJECT_CUR\u0000*/, "");
|
||||
CFB.utils.cfb_add(newcfb, newpath, cfb.FileIndex[i].content);
|
||||
});
|
||||
return CFB.write(newcfb);
|
||||
}
|
||||
RELS.DS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/dialogsheet";
|
||||
RELS.MS = "http://schemas.microsoft.com/office/2006/relationships/xlMacrosheet";
|
||||
|
||||
@ -12792,7 +12829,8 @@ function parse_wb_xml(data, opts) {
|
||||
|
||||
/* Others */
|
||||
case '<ArchID': break;
|
||||
case '<AlternateContent': pass=true; break;
|
||||
case '<AlternateContent':
|
||||
case '<AlternateContent>': pass=true; break;
|
||||
case '</AlternateContent>': pass=false; break;
|
||||
|
||||
/* TODO */
|
||||
@ -15193,6 +15231,7 @@ else {
|
||||
/* Quattro Pro 9 */
|
||||
else if((_data=CFB.find(cfb, 'NativeContent_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
|
||||
else throw new Error("Cannot find Workbook stream");
|
||||
if(options.bookVBA && CFB.find(cfb, '/_VBA_PROJECT_CUR/VBA/dir')) WorkbookP.vbaraw = make_vba_xls(cfb);
|
||||
}
|
||||
|
||||
var props = {};
|
||||
|
Loading…
Reference in New Issue
Block a user