parse self-closing text:p uof:文本串 (fixes #2927)

This commit is contained in:
SheetJS 2023-04-30 03:57:30 -04:00
parent b68eaed726
commit 5b33acfaf4
36 changed files with 11 additions and 459 deletions

1
.gitignore vendored

@ -14,6 +14,7 @@ tmp
*.[pP][mM][dD]*
*.[pP][dD][fF]
*.[sS][lL][kK]
*.[sS][yY][lL][kK]
*.socialcalc
*.[xX][lL][sSwWcCaAtTmMrR]
*.[xX][lL][sSaAtT][xXmMbB]

@ -4,10 +4,13 @@ This log is intended to keep track of backwards-incompatible changes, including
but not limited to API changes and file location changes. Minor behavioral
changes may not be included if they are not expected to break existing code.
* Export `NaN` values to `#NUM!` and infinite values to `#DIV/0!`
## v0.19.3
* XLSX Ensure comment address is valid (h/t @slonser)
* Enforce Excel worksheet name restrictions
* Fixed "Prototype Pollution" vulnerability (CVE-2023-30533)
## v0.19.2

@ -9,7 +9,7 @@ Edit complex templates with ease; let out your inner Picasso with styling; make
custom sheets with images/graphs/PivotTables; evaluate formula expressions and
port calculations to web apps; automate common spreadsheet tasks, and much more!
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/sheetjs?pixel)](https://github.com/SheetJS/sheetjs)
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/sheetjs?pixel)](https://git.sheetjs.com/SheetJS/sheetjs)
[![Build Status](https://saucelabs.com/browser-matrix/sheetjs.svg)](https://saucelabs.com/u/sheetjs)
@ -29,9 +29,9 @@ port calculations to web apps; automate common spreadsheet tasks, and much more!
- [`test_files`](https://github.com/SheetJS/test_files): Sample spreadsheets
- [`cfb`](https://github.com/SheetJS/js-cfb): Container (OLE/ZIP) format library
- [`cfb`](https://git.sheetjs.com/SheetJS/js-cfb): Container (OLE/ZIP) format library
- [`codepage`](https://github.com/SheetJS/js-codepage): Legacy text encodings
- [`codepage`](https://git.sheetjs.com/SheetJS/js-codepage): Legacy text encodings
## License

@ -596,6 +596,9 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
if(Rn[1]==='/' && (!ctag || !ctag['string-value'])) {
var ptp = parse_text_p(str.slice(textpidx,Rn.index), textptag);
textp = (textp.length > 0 ? textp + "\n" : "") + ptp[0];
} else if(Rn[0].slice(-2) == "/>") {
/* TODO: is self-closing 文本串 valid? */
textp += "\n";
} else { textptag = parsexmltag(Rn[0], false); textpidx = Rn.index + Rn[0].length; }
break; // <text:p>
case 's': break; // <text:s>

@ -1,78 +0,0 @@
# Demos
These demos are intended to demonstrate how to load this library in various
ecosystems. The library is designed to be used in the web browser and in node
contexts, using dynamic feature tests to pull in features when necessary. This
works extremely well in common use cases: script tag insertion and node require.
Systems like webpack try to be clever by performing simple static analysis to
pull in code. However, they do not support dynamic type tests, breaking
compatibility with traditional scripts. Configuration is required. The demos
cover basic configuration steps for various systems and should "just work".
Mobile app and other larger demos do not include the full build structure. The
demos have `Makefile` scripts that show how to reproduce the full projects. The
scripts have been tested against iOS and OSX. For Windows platforms, GNU make
can be installed with Bash on Windows or with `cygwin`.
### Included Demos
**JavaScript APIs**
- [`XMLHttpRequest and fetch`](https://docs.sheetjs.com/docs/demos/network)
- [`Clipboard Data`](https://docs.sheetjs.com/docs/demos/clipboard)
- [`Typed Arrays for Machine Learning`](https://docs.sheetjs.com/docs/demos/ml)
- [`LocalStorage and SessionStorage`](https://docs.sheetjs.com/docs/demos/database#localstorage-and-sessionstorage)
- [`Web SQL Database`](https://docs.sheetjs.com/docs/demos/database#websql)
- [`IndexedDB`](https://docs.sheetjs.com/docs/demos/database#indexeddb)
**Frameworks**
- [`Angular 2+ and Ionic`](https://docs.sheetjs.com/docs/demos/angular)
- [`React`](https://docs.sheetjs.com/docs/demos/react)
- [`VueJS`](https://docs.sheetjs.com/docs/demos/vue)
- [`Angular.JS`](https://docs.sheetjs.com/docs/demos/legacy#angularjs)
- [`Knockout`](https://docs.sheetjs.com/docs/demos/legacy#knockoutjs)
**Front-End UI Components**
- [`canvas-datagrid`](https://docs.sheetjs.com/docs/demos/grid#canvas-datagrid)
- [`x-spreadsheet`](https://docs.sheetjs.com/docs/demos/grid#x-spreadsheet)
- [`react-data-grid`](https://docs.sheetjs.com/docs/demos/grid#react-data-grid)
- [`vue3-table-lite`](https://docs.sheetjs.com/docs/demos/grid#vue3-table-lite)
- [`angular-ui-grid`](https://docs.sheetjs.com/docs/demos/grid#angular-ui-grid)
**Platforms and Integrations**
- [`Command-Line Tools`](https://docs.sheetjs.com/docs/demos/cli)
- [`iOS and Android Mobile Applications`](https://docs.sheetjs.com/docs/demos/mobile)
- [`NodeJS Server-Side Processing`](https://docs.sheetjs.com/docs/demos/server#nodejs)
- [`Content Management and Static Sites`](https://docs.sheetjs.com/docs/demos/content)
- [`Electron`](https://docs.sheetjs.com/docs/demos/desktop#electron)
- [`NW.js`](https://docs.sheetjs.com/docs/demos/desktop#nwjs)
- [`Tauri`](https://docs.sheetjs.com/docs/demos/desktop#tauri)
- [`Chrome and Chromium Extensions`](https://docs.sheetjs.com/docs/demos/chromium)
- [`Google Sheets API`](https://docs.sheetjs.com/docs/demos/gsheet)
- [`ExtendScript for Adobe Apps`](https://docs.sheetjs.com/docs/demos/extendscript)
- [`NetSuite SuiteScript`](https://docs.sheetjs.com/docs/demos/netsuite)
- [`SalesForce Lightning Web Components`](https://docs.sheetjs.com/docs/demos/salesforce)
- [`Excel JavaScript API`](https://docs.sheetjs.com/docs/demos/excel)
- [`Headless Automation`](https://docs.sheetjs.com/docs/demos/headless)
- [`Other JavaScript Engines`](https://docs.sheetjs.com/docs/demos/engines)
- [`Azure Functions and Storage`](https://docs.sheetjs.com/docs/demos/azure)
- [`Amazon Web Services`](https://docs.sheetjs.com/docs/demos/aws)
- [`Databases and Structured Data Stores`](https://docs.sheetjs.com/docs/demos/database)
- [`NoSQL and Unstructured Data Stores`](https://docs.sheetjs.com/docs/demos/nosql)
- [`Legacy Internet Explorer`](https://docs.sheetjs.com/docs/demos/legacy#internet-explorer)
**Bundlers and Tooling**
- [`browserify`](https://docs.sheetjs.com/docs/demos/bundler#browserify)
- [`bun`](https://docs.sheetjs.com/docs/demos/bundler#bun)
- [`esbuild`](https://docs.sheetjs.com/docs/demos/bundler#esbuild)
- [`parcel`](https://docs.sheetjs.com/docs/demos/bundler#parcel)
- [`requirejs`](https://docs.sheetjs.com/docs/demos/bundler#requirejs)
- [`rollup`](https://docs.sheetjs.com/docs/demos/bundler#rollup)
- [`snowpack`](https://docs.sheetjs.com/docs/demos/bundler#snowpack)
- [`swc`](https://docs.sheetjs.com/docs/demos/bundler#swc)
- [`systemjs`](https://docs.sheetjs.com/docs/demos/bundler#systemjs)
- [`vite`](https://docs.sheetjs.com/docs/demos/bundler#vite)
- [`webpack`](https://docs.sheetjs.com/docs/demos/bundler#webpack)
- [`wmr`](https://docs.sheetjs.com/docs/demos/bundler#wmr)
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,7 +0,0 @@
# Other JS Engines and Deployments
[The new demo](https://docs.sheetjs.com/docs/demos/engines)
includes more detailed instructions and more JS engines.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,10 +0,0 @@
# AngularJS
The content has been reorganized;
- [The "Legacy Frameworks" section](https://docs.sheetjs.com/docs/demos/legacy#angularjs)
covers the AngularJS basics.
- [The "Angular UI Grid" section](https://docs.sheetjs.com/docs/demos/legacy#angularjs)
covers the integration with Angular UI Grid.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,11 +0,0 @@
# Angular 2+
[The new demo](https://docs.sheetjs.com/docs/demos/angular) has an updated
exposition for legacy and modern deployments alike.
The ecosystem demos were grouped by type in the new demo site:
- [NativeScript](https://docs.sheetjs.com/docs/demos/mobile#nativescript) is now part of "iOS and Android Apps"
- [Ionic](https://docs.sheetjs.com/docs/demos/mobile#ionic) is now part of "iOS and Android Apps"
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,6 +0,0 @@
# Typed Arrays and Math
[The new demo](https://docs.sheetjs.com/docs/demos/ml) includes
interactive examples as well as strategies for CSV and JS Array interchange.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,6 +0,0 @@
# Browserify
[The new demo](https://docs.sheetjs.com/docs/demos/bundler#browserify)
includes a more concise example.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,6 +0,0 @@
# Chrome and Chromium
[The new demo](https://docs.sheetjs.com/docs/demos/chromium)
includes more up-to-date details.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,11 +0,0 @@
# Databases
This demo has been split up for clarity:
- <https://docs.sheetjs.com/docs/demos/database> covers SQL and
structured data (including CRUD operations)
- https://docs.sheetjs.com/docs/demos/nosql covers unstructured
data including "NoSQL" data stores.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,7 +0,0 @@
# canvas-datagrid
[The new demo](https://docs.sheetjs.com/docs/demos/grid#canvas-datagrid)
includes a live example and improved explanations.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,13 +0,0 @@
# Deno
Deno is a runtime capable of running JS code including this library.
Demos have been integrated in the [documentation](https://docs.sheetjs.com) :
- <https://docs.sheetjs.com/docs/installation/deno> installation
- <https://docs.sheetjs.com/docs/example> writing JS data to a spreadsheet
- <https://docs.sheetjs.com/docs/solutions/input> input strategies
- <https://docs.sheetjs.com/docs/solutions/output> output strategies
- <https://docs.sheetjs.com/docs/demos/cli#deno> `deno compile`
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,6 +0,0 @@
# Electron
[The new demo](https://docs.sheetjs.com/docs/demos/desktop#electron)
includes an improved example and detailed explanations.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,7 +0,0 @@
# Adobe ExtendScript
[The new demo](https://docs.sheetjs.com/docs/demos/extendscript)
has a more focused Photoshop example as well as notes about other extensibility
frameworks shipping with newer versions of Creative Cloud apps.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,9 +0,0 @@
# "Serverless" Functions
Cloud services are covered in separate demos:
- [AWS](https://docs.sheetjs.com/docs/demos/aws)
- [Azure](https://docs.sheetjs.com/docs/demos/azure)
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,9 +0,0 @@
# Google Sheets API
The old demo used a deprecated version of the Google Sheets API to export data
from Google Sheets Documents.
[The new demo](https://docs.sheetjs.com/docs/demos/gsheet) uses
the new Google Sheets API to read and write data.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,8 +0,0 @@
# Headless Browsers
[The new demo](https://docs.sheetjs.com/docs/demos/headless)
has a more focused table export example as well as a demo script for Chromium
automation with Puppeteer and multi-browser automation with Playwright.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,7 +0,0 @@
# Knockout
[The new demo](https://docs.sheetjs.com/docs/demos/legacy#knockoutjs)
includes a live example and improved explanations.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,8 +0,0 @@
# Meteor
This demo originally covered Meteor's package manager and other nuances. At the
time the demo was written, Meteor had its own ecosystem that clashed with the
burgeoning NodeJS package ecosystem. Eventually, Meteor added proper support
for NodeJS modules. New projects should follow the instructions for packages.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,6 +0,0 @@
# NW.js
[The new demo](https://docs.sheetjs.com/docs/demos/desktop#nwjs)
includes an improved example and detailed explanations.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,6 +0,0 @@
# Internet Explorer
[The new demo](https://docs.sheetjs.com/docs/demos/legacy#internet-explorer)
includes a live example and easier integration bundle.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,6 +0,0 @@
# Parcel
[The new demo](https://docs.sheetjs.com/docs/demos/bundler#parcel)
includes a more concise example.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,12 +0,0 @@
# React
[The new demo](https://docs.sheetjs.com/docs/demos/react) has an updated
exposition for legacy and modern deployments alike.
The ecosystem demos were grouped by type in the new demo site:
- [server-rendered React components with `next.js`](https://docs.sheetjs.com/docs/demos/content#nextjs) is now part of "Content and Site Generation"
- [`react-native` deployment for iOS and android](https://docs.sheetjs.com/docs/demos/mobile#react-native) is now part of "iOS and Android Apps"
- [`react-data-grid` reading, modifying, and writing files](https://docs.sheetjs.com/docs/demo/grid#react-data-grid) is now part of "Data Grids and UI"
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,7 +0,0 @@
# RequireJS
[The new demo](https://docs.sheetjs.com/docs/demos/bundler#requirejs)
includes a live example and improved explanations.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,7 +0,0 @@
# Rollup
[The new demo](https://docs.sheetjs.com/docs/demos/bundler#rollup)
includes a simple example and improved explanations.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,11 +0,0 @@
# NodeJS Server Deployments
[The new demo](https://docs.sheetjs.com/docs/demos/server) has a more focused
discussion with examples for popular JS server-side frameworks.
Cloud services are covered in separate demos:
- [AWS](https://docs.sheetjs.com/docs/demos/aws)
- [Azure](https://docs.sheetjs.com/docs/demos/azure)
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,6 +0,0 @@
# SystemJS Demos
[The new demo](https://docs.sheetjs.com/docs/demos/bundler#systemjs)
includes a live example and improved explanations.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,9 +0,0 @@
# TypeScript
This demo originally covered direct use of the `tsc` TypeScript compiler. At
the time when the demo was first written, TypeScript 2.2 had a module system
that was incompatible with the pure JS ecosystem. Since then, various
language improvements and compiler changes have obviated this demo. Uses of
TypeScript are scattered throughout other demos.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,12 +0,0 @@
# VueJS
[The new demo](https://docs.sheetjs.com/docs/demos/vue) has an updated
exposition for legacy and modern deployments alike.
The ecosystem demos were grouped by type in the new demo site:
- [Nuxt Content](https://docs.sheetjs.com/docs/demos/content#nuxtjs) is now part of "Content and Site Generation"
- [The new iOS app demo](https://docs.sheetjs.com/docs/demos/mobile#quasar) uses the Quasar Framework in a VueJS + Vite project to generate a native iOS app.
- [`vue3-table-lite` reading, modifying, and writing files](https://docs.sheetjs.com/docs/demos/grid#vue3-table-lite) is now part of "Data Grids and UI"
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,6 +0,0 @@
# Webpack
[The new demo](https://docs.sheetjs.com/docs/demos/bundler#webpack)
reflects the new default behavior to use the ESM build.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,7 +0,0 @@
# XMLHttpRequest and fetch
[The new demo](https://docs.sheetjs.com/docs/demos/network)
includes interactive demos and improved explanations.
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,18 +0,0 @@
# x-spreadsheet
The `sheet_to_json` utility function generates output arrays suitable for use
with other JS libraries such as data grids for previewing data. With a familiar
UI, [`x-spreadsheet`](https://myliang.github.io/x-spreadsheet/) is an excellent
choice for developers looking for a modern editor.
[The new docs](https://docs.sheetjs.com/docs/demos/grid/#x-spreadsheet)
include more detail and examples.
The original demo is available at <https://docs.sheetjs.com/xspreadsheet/>
A hosted version of the `xlsxspread.js` script is available on the SheetJS CDN:
- <https://cdn.sheetjs.com/xspreadsheet/xlsxspread.js> original script
- <https://cdn.sheetjs.com/xspreadsheet/xlsxspread.min.js> minified
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)

@ -1,133 +0,0 @@
/*! xlsxspread.js (C) SheetJS LLC -- https://sheetjs.com/ */
/* eslint-env browser */
/*global XLSX */
/*exported stox, xtos */
console.log("The latest version of the xlsxspread.js script is at https://cdn.sheetjs.com/xspreadsheet/xlsxspread.js !")
/**
* Converts data from SheetJS to x-spreadsheet
*
* @param {Object} wb SheetJS workbook object
*
* @returns {Object[]} An x-spreadsheet data
*/
function stox(wb) {
var out = [];
wb.SheetNames.forEach(function (name) {
var o = { name: name, rows: {} };
var ws = wb.Sheets[name];
if(!ws || !ws["!ref"]) return;
var range = XLSX.utils.decode_range(ws['!ref']);
// sheet_to_json will lost empty row and col at begin as default
range.s = { r: 0, c: 0 };
var aoa = XLSX.utils.sheet_to_json(ws, {
raw: false,
header: 1,
range: range
});
aoa.forEach(function (r, i) {
var cells = {};
r.forEach(function (c, j) {
cells[j] = { text: c };
var cellRef = XLSX.utils.encode_cell({ r: i, c: j });
if ( ws[cellRef] != null && ws[cellRef].f != null) {
cells[j].text = "=" + ws[cellRef].f;
}
});
o.rows[i] = { cells: cells };
});
o.merges = [];
(ws["!merges"]||[]).forEach(function (merge, i) {
//Needed to support merged cells with empty content
if (o.rows[merge.s.r] == null) {
o.rows[merge.s.r] = { cells: {} };
}
if (o.rows[merge.s.r].cells[merge.s.c] == null) {
o.rows[merge.s.r].cells[merge.s.c] = {};
}
o.rows[merge.s.r].cells[merge.s.c].merge = [
merge.e.r - merge.s.r,
merge.e.c - merge.s.c
];
o.merges[i] = XLSX.utils.encode_range(merge);
});
out.push(o);
});
return out;
}
/**
* Converts data from x-spreadsheet to SheetJS
*
* @param {Object[]} sdata An x-spreadsheet data object
*
* @returns {Object} A SheetJS workbook object
*/
function xtos(sdata) {
var out = XLSX.utils.book_new();
sdata.forEach(function (xws) {
var ws = {};
var rowobj = xws.rows;
var minCoord = { r: 0, c: 0 }, maxCoord = { r: 0, c: 0 };
for (var ri = 0; ri < rowobj.len; ++ri) {
var row = rowobj[ri];
if (!row) continue;
Object.keys(row.cells).forEach(function (k) {
var idx = +k;
if (isNaN(idx)) return;
var lastRef = XLSX.utils.encode_cell({ r: ri, c: idx });
if (ri > maxCoord.r) maxCoord.r = ri;
if (idx > maxCoord.c) maxCoord.c = idx;
var cellText = row.cells[k].text, type = "s";
if (!cellText) {
cellText = "";
type = "z";
} else if (!isNaN(Number(cellText))) {
cellText = Number(cellText);
type = "n";
} else if (cellText.toLowerCase() === "true" || cellText.toLowerCase() === "false") {
cellText = Boolean(cellText);
type = "b";
}
ws[lastRef] = { v: cellText, t: type };
if (type == "s" && cellText[0] == "=") {
ws[lastRef].f = cellText.slice(1);
}
if (row.cells[k].merge != null) {
if (ws["!merges"] == null) ws["!merges"] = [];
ws["!merges"].push({
s: { r: ri, c: idx },
e: {
r: ri + row.cells[k].merge[0],
c: idx + row.cells[k].merge[1]
}
});
}
});
}
ws["!ref"] = minCoord ? XLSX.utils.encode_range({
s: minCoord,
e: maxCoord
}) : "A1";
XLSX.utils.book_append_sheet(out, ws, xws.name);
});
return out;
}

@ -2,7 +2,7 @@
set -eo pipefail
INF=${1:-test.numbers}
OUTF=${2:-reframed.numbers}
chmod a+w "$OUTF"
if [ -e "$OUTF" ]; then chmod a+w "$OUTF"; fi
cp "$INF" "$OUTF"
chmod a-w "$OUTF"
sleep 0.1