forked from sheetjs/sheetjs
Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
318e2319ee | |||
6c0f950f83 | |||
235ed7ccfb | |||
2d6c821261 | |||
36debb0eaa | |||
df48a059c3 |
@ -7,6 +7,7 @@ changes may not be included if they are not expected to break existing code.
|
||||
* Sheet Visibility for ODS / FODS (h/t @edemaine)
|
||||
* HTML DOM ingress support formulae (`data-f`)
|
||||
* Proper handling of XLSX encoded entities (h/t @inreoh)
|
||||
* Proper handling of invalid DIF sheets that match heuristics (h/t @lowkeyfish)
|
||||
|
||||
## v0.20.3
|
||||
|
||||
|
@ -1,69 +1,74 @@
|
||||
# Contributing
|
||||
|
||||
The SheetJS Libraries should be free and clear to use in your projects. In
|
||||
order to maintain that, every contributor must be vigilant.
|
||||
SheetJS CE should be free and clear to use in your projects. To ensure that
|
||||
remains true, each contributor must be vigilant and each contribution must be
|
||||
carefully scrutinized from a technical and legal perspective.
|
||||
|
||||
There have been many projects in the past that have been very lax regarding
|
||||
licensing. We are of the opinion that those are ticking timebombs and that no
|
||||
commercial product should depend on them.
|
||||
Many commercial products and open source projects have been very lax regarding
|
||||
licensing. They are ticking timebombs that no commercial product should use.
|
||||
|
||||
|
||||
# Required Reading
|
||||
## Required Reading
|
||||
|
||||
These are pretty short reads and emphasize the importance of proper licensing:
|
||||
|
||||
- https://github.com/jazzband/tablib/issues/114 (discussion of other tools)
|
||||
- https://web.archive.org/web/20200916173942/https://github.com/jazzband/tablib/issues/114
|
||||
|
||||
- https://web.archive.org/web/20120615223756/http://www.codinghorror.com/blog/2007/04/pick-a-license-any-license.html
|
||||
- https://web.archive.org/web/20240909210554/https://github.com/stephen-hardy/xlsx.js/issues/8
|
||||
|
||||
|
||||
# Raising Issues
|
||||
## Raising Issues
|
||||
|
||||
Issues should generally be accompanied by test files. Since github does not
|
||||
support attachments, the best method is to send files to <sheetjs@gmail.com>
|
||||
(subject line should contain issue number or message) or to share using some
|
||||
storage service. Unless expressly permitted, any attachments will not be
|
||||
shared or included in a test suite (although I will ask :)
|
||||
Issues should generally be accompanied by test files. It is strongly recommended
|
||||
to use the [issue tracker](https://git.sheetjs.com/sheetjs/sheetjs/issues).
|
||||
|
||||
If sending email to a gmail account is problematic, the <dev@sheetjs.com> email
|
||||
inbox is self-hosted.
|
||||
If they cannot be shared publicly, please send files to <oss@sheetjs.com>
|
||||
(subject line should contain issue number or message) or share links to files
|
||||
hosted on a storage service. Unless expressly permitted, attachments will not be
|
||||
shared outside of SheetJS LLC or included in a test suite.
|
||||
|
||||
# Opening Pull Requests
|
||||
If a NDA is required, please send an email to <oss@sheetjs.com> with subject
|
||||
line "Non-Disclosure Agreemeant Request".
|
||||
|
||||
[Squash commits](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History)
|
||||
before opening a pull request, If the pull request addresses documentation or
|
||||
demos, add `[ci skip]` in the body or title of the commit message to skip tests.
|
||||
|
||||
# Pre-Contribution Checklist
|
||||
## Opening Pull Requests
|
||||
|
||||
Please raise an issue before opening pull requests. It is easy to solve a
|
||||
specific problem without considering the full context or implications.
|
||||
|
||||
|
||||
## Pre-Contribution Checklist
|
||||
|
||||
Before thinking about contributing, make sure that:
|
||||
|
||||
- You are not, nor have ever been, an employee of Microsoft Corporation.
|
||||
|
||||
- You have not signed any NDAs or Shared Source Agreements with Microsoft
|
||||
Corporation or a subsidiary
|
||||
Corporation or a subsidiary.
|
||||
|
||||
- You have not consulted any existing relevant codebase (if you have, please
|
||||
take note of which codebases were consulted).
|
||||
|
||||
If you cannot attest to each of these items, the best approach is to raise an
|
||||
issue. If it is a particularly high-priority issue, please drop an email to
|
||||
<sheetjs@gmail.com> and it will be prioritized.
|
||||
issue. If it is a particularly high-priority issue, please drop an email to
|
||||
<support@sheetjs.com> and it will be prioritized.
|
||||
|
||||
|
||||
# Intra-Contribution
|
||||
## Intra-Contribution
|
||||
|
||||
Keep these in mind as you work:
|
||||
|
||||
- Your contributions are your original work. Take note of any resources you
|
||||
- Your contributions are your original work. Take note of any resources you
|
||||
consult in the process. Be extra careful not to use unlicensed code on the
|
||||
Internet or code generated by a large language model or other AI tool.
|
||||
|
||||
- You are working on your own time. Unless they explicitly grant permission,
|
||||
- You are working on your own time. Unless they explicitly grant permission,
|
||||
your employer may be the ultimate owner of your IP
|
||||
|
||||
# Post-Contribution
|
||||
|
||||
Before contributions are merged, you will receive an email (at the address
|
||||
associated with the git commit) and will be asked to confirm the aforementioned
|
||||
items. Ensure that the email addresses associated with the commits are valid.
|
||||
## Post-Contribution
|
||||
|
||||
Before certain contributions are merged, you will receive an email (at the
|
||||
address associated with the git commit) and will be asked to confirm the
|
||||
aforementioned items. Ensure that the email addresses associated with the
|
||||
commits are valid.
|
||||
|
@ -421,7 +421,11 @@ function hashq(str/*:string*/)/*:string*/ {
|
||||
}
|
||||
return o;
|
||||
}
|
||||
function rnd(val/*:number*/, d/*:number*/)/*:string*/ { var dd = Math.pow(10,d); return ""+(Math.round(val * dd)/dd); }
|
||||
function rnd(val/*:number*/, d/*:number*/)/*:string*/ {
|
||||
var sgn = val < 0 ? -1 : 1;
|
||||
var dd = Math.pow(10,d);
|
||||
return ""+sgn*(Math.round(sgn * val * dd)/dd);
|
||||
}
|
||||
function dec(val/*:number*/, d/*:number*/)/*:number*/ {
|
||||
var _frac = val - Math.floor(val), dd = Math.pow(10,d);
|
||||
if (d < ('' + Math.round(_frac * dd)).length) return 0;
|
||||
|
@ -153,7 +153,13 @@ function utf8readb(data) {
|
||||
function utf8readc(data) { return Buffer_from(data, 'binary').toString('utf8'); }
|
||||
|
||||
var utf8corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3";
|
||||
var utf8read = has_buf && (/*#__PURE__*/utf8readc(utf8corpus) == /*#__PURE__*/utf8reada(utf8corpus) && utf8readc || /*#__PURE__*/utf8readb(utf8corpus) == /*#__PURE__*/utf8reada(utf8corpus) && utf8readb) || utf8reada;
|
||||
var utf8read = /*#__PURE__*/(function() {
|
||||
if(has_buf) {
|
||||
if(utf8readc(utf8corpus) == utf8reada(utf8corpus)) return utf8readc;
|
||||
if(utf8readb(utf8corpus) == utf8reada(utf8corpus)) return utf8readb;
|
||||
}
|
||||
return utf8reada;
|
||||
})();
|
||||
|
||||
var utf8write/*:StringConv*/ = has_buf ? function(data) { return Buffer_from(data, 'utf8').toString("binary"); } : function(orig/*:string*/)/*:string*/ {
|
||||
var out/*:Array<string>*/ = [], i = 0, c = 0, d = 0;
|
||||
|
@ -1138,3 +1138,17 @@ function read_wb_ID(d, opts) {
|
||||
}
|
||||
}
|
||||
|
||||
function read_wb_TABL(d, opts) {
|
||||
var o = opts || {}, OLD_WTF = !!o.WTF; o.WTF = true;
|
||||
try {
|
||||
var out = DIF.to_workbook(d, o);
|
||||
if(!out || !out.Sheets) throw "DIF bad workbook";
|
||||
var ws = out.Sheets[out.SheetNames[0]];
|
||||
if(!ws || !ws["!ref"]) throw "DIF empty worksheet";
|
||||
o.WTF = OLD_WTF;
|
||||
return out;
|
||||
} catch(e) {
|
||||
o.WTF = OLD_WTF;
|
||||
return PRN.to_workbook(d, opts);
|
||||
}
|
||||
}
|
||||
|
@ -431,8 +431,54 @@ function write_FMTS_biff8(ba, NF/*:?SSFTable*/, opts) {
|
||||
});
|
||||
}
|
||||
|
||||
function write_ws_protect_biff8(sp) {
|
||||
/* SheetProtection */
|
||||
var flags = 0x0000;
|
||||
[
|
||||
["objects", false, 0x0001], // fObjects - Bit 0 (Edit objects)
|
||||
["scenarios", false, 0x0002], // fScenarios - Bit 1 (Edit scenarios)
|
||||
["formatCells", true, 0x0004], // fFormatCells - Bit 2 (Change cell formatting)
|
||||
["formatColumns", true, 0x0008], // fFormatColumns - Bit 3 (Change column formatting)
|
||||
["formatRows", true, 0x0010], // fFormatRows - Bit 4 (Change row formatting)
|
||||
["insertColumns", true, 0x0020], // fInsertColumns - Bit 5 (Insert columns)
|
||||
["insertRows", true, 0x0040], // fInsertRows - Bit 6 (Insert rows)
|
||||
["insertHyperlinks", true, 0x0080], // fInsertHyperlinks - Bit Bit 7 (Insert hyperlinks)
|
||||
["deleteColumns", true, 0x0100], // fDeleteColumns - Bit 8 (Delete columns)
|
||||
["deleteRows", true, 0x0200], // fDeleteRows - Bit 9 (Delete rows)
|
||||
["selectLockedCells", false, 0x0400], // fSelLockedCells - Bit 10 (Select locked cells)
|
||||
["sort", true, 0x0800], // fSort - Bit 11 (Sort a cell range)
|
||||
["autoFilter", true, 0x1000], // fAutoFilter - Bit 12 (Edit auto filters)
|
||||
["pivotTables", true, 0x2000], // fPivotTables - Bit 13 (Edit PivotTables)
|
||||
["selectUnlockedCells", false, 0x4000] // fSelUnlockedCells - Bit 14 (Select unlocked cells)
|
||||
].forEach(function(n) {
|
||||
if(n[1]) flags |= sp[n[0]] != null && !sp[n[0]] ? n[2] : 0x0000;
|
||||
else flags |= sp[n[0]] != null && sp[n[0]] ? 0x0000 : n[2];
|
||||
});
|
||||
|
||||
/* [MS-XLS] 2.4.112 */
|
||||
var featHdr = new_buf(23);
|
||||
/* [MS-XLS] 2.5.135 */
|
||||
featHdr.write_shift(2, 0x0867);
|
||||
featHdr.write_shift(2, 0x0000);
|
||||
featHdr.write_shift(4, 0x00000000);
|
||||
featHdr.write_shift(4, 0x00000000);
|
||||
/* [MS-XLS] 2.5.237 */
|
||||
featHdr.write_shift(2, 0x0002); // SharedFeatureType ISFPROTECTION
|
||||
/* Reserved byte */
|
||||
featHdr.write_shift(1, 0x01);
|
||||
/* cbHdrData */
|
||||
featHdr.write_shift(4, 0xffffffff);
|
||||
/* [MS-XLS] 2.5.104 */
|
||||
featHdr.write_shift(4, flags);
|
||||
|
||||
return featHdr;
|
||||
}
|
||||
|
||||
function write_FEAT(ba, ws) {
|
||||
/* [MS-XLS] 2.4.112 */
|
||||
/* ISFPROTECTION */
|
||||
if(ws['!protect']) write_biff_rec(ba, 0x0867 /* FeatHdr */, write_ws_protect_biff8(ws['!protect']));
|
||||
/* ISFFEC2 */
|
||||
var o = new_buf(19);
|
||||
o.write_shift(4, 0x867); o.write_shift(4, 0); o.write_shift(4, 0);
|
||||
o.write_shift(2, 3); o.write_shift(1, 1); o.write_shift(4, 0);
|
||||
@ -537,6 +583,14 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
|
||||
/* Footer (string) */
|
||||
write_biff_rec(ba, 0x0083 /* HCenter */, writebool(false));
|
||||
write_biff_rec(ba, 0x0084 /* VCenter */, writebool(false));
|
||||
/* PROTECTION */
|
||||
if(ws['!protect']){
|
||||
var sp = ws['!protect'];
|
||||
/* [MS-XLS] 2.4.207 */
|
||||
write_biff_rec(ba, 0x0012 /* Protect */, writeuint16(1));
|
||||
/* [MS-XLS] 2.4.191 */
|
||||
if(sp.password) write_biff_rec(ba, 0x0013 /* Password */, writeuint16(crypto_CreatePasswordVerifier_Method1(sp.password)));
|
||||
}
|
||||
/* ... */
|
||||
if(b8) write_ws_cols_biff8(ba, ws["!cols"]);
|
||||
/* ... */
|
||||
|
@ -764,6 +764,10 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
|
||||
_Ref = ods_to_csf_3D(atag.Target.slice(1));
|
||||
atag.Target = "#" + _Ref[0] + "!" + _Ref[1];
|
||||
} else if(atag.Target.match(/^\.\.[\\\/]/)) atag.Target = atag.Target.slice(3);
|
||||
/* Appendix D.2 Hyperlink Titles */
|
||||
if(atag.title) {
|
||||
atag.Tooltip = unescapexml(atag.title); delete atag.title;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -99,7 +99,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
if(n[1] === 0x49 && n[2] === 0x2a && n[3] === 0x00) throw new Error("TIFF Image File is not a spreadsheet");
|
||||
if(n[1] === 0x44) return read_wb_ID(d, o);
|
||||
break;
|
||||
case 0x54: if(n[1] === 0x41 && n[2] === 0x42 && n[3] === 0x4C) return DIF.to_workbook(d, o); break;
|
||||
case 0x54: if(n[1] === 0x41 && n[2] === 0x42 && n[3] === 0x4C) return read_wb_TABL(d, o); break;
|
||||
case 0x50: return (n[1] === 0x4B && n[2] < 0x09 && n[3] < 0x09) ? read_zip(d, o) : read_prn(data, d, o, str);
|
||||
case 0xEF: return n[3] === 0x3C ? parse_xlml(d, o) : read_prn(data, d, o, str);
|
||||
case 0xFF:
|
||||
|
@ -111,7 +111,7 @@ function write_binary_type(out, opts/*:WriteOpts*/)/*:any*/ {
|
||||
|
||||
function writeSyncXLSX(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
reset_cp();
|
||||
check_wb(wb);
|
||||
if(!opts || !opts.unsafe) check_wb(wb);
|
||||
var o = dup(opts||{});
|
||||
if(o.cellStyles) { o.cellNF = true; o.sheetStubs = true; }
|
||||
if(o.type == "array") { o.type = "binary"; var out/*:string*/ = (writeSyncXLSX(wb, o)/*:any*/); o.type = "array"; return s2ab(out); }
|
||||
@ -120,7 +120,7 @@ function writeSyncXLSX(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
|
||||
function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
reset_cp();
|
||||
check_wb(wb);
|
||||
if(!opts || !opts.unsafe) check_wb(wb);
|
||||
var o = dup(opts||{});
|
||||
if(o.cellStyles) { o.cellNF = true; o.sheetStubs = true; }
|
||||
if(o.type == "array") { o.type = "binary"; var out/*:string*/ = (writeSync(wb, o)/*:any*/); o.type = "array"; return s2ab(out); }
|
||||
|
3
types/index.d.ts
vendored
3
types/index.d.ts
vendored
@ -317,6 +317,9 @@ export interface WritingOptions extends CommonOptions {
|
||||
|
||||
/** Record Separator ("row separator") for CSV / Text output */
|
||||
RS?: string;
|
||||
|
||||
/** Skip certain validity checks (NOTE: generated files may not open in Excel) */
|
||||
unsafe?: boolean;
|
||||
}
|
||||
|
||||
/** Workbook Object */
|
||||
|
Loading…
Reference in New Issue
Block a user