This commit is contained in:
SheetJS 2022-08-06 21:57:38 -04:00
parent 9612e25631
commit a1f9f5e4d9
3 changed files with 394 additions and 0 deletions

View File

@ -771,6 +771,194 @@ Click on "Click here to export" to generate a file.
</details>
## SystemJS
With configuration, SystemJS supports both browser and NodeJS deployments.
:::caution
This demo was written against SystemJS 0.19, the most popular SystemJS version.
used with Angular applications. In the years since the release, Angular and
other tools using SystemJS have switched to Webpack.
:::
<Tabs>
<TabItem value="browser" label="Browser">
SystemJS fails by default because the library does not export anything in the
web browser. The `meta` configuration option can be used to expose `XLSX`:
```js
SystemJS.config({
meta: {
'xlsx': {
exports: 'XLSX' // <-- tell SystemJS to expose the XLSX variable
}
},
map: {
'xlsx': 'https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js',
'fs': '', // <--|
'crypto': '', // <--| suppress native node modules
'stream': '' // <--|
}
});
SystemJS.import('main.js'); // load `main.js`
```
The `main.js` script can freely `require("xlsx")`.
:::caution Web Workers
Web Workers can load the SystemJS library with `importScripts`, but the imported
code cannot assign the original worker's `onmessage` callback. The recommended
approach is to expose a global from the required script, For example, supposing
the shared name is `_cb`, the primary worker script would call the callback:
```js title="worker.js"
/* main worker script */
importScripts('system.js');
SystemJS.config({ /* ... browser config ... */ });
onmessage = function(evt) {
SystemJS.import('workermain.js').then(function() { _cb(evt); });
};
```
The worker script would define and expose the function:
```js title="workermain.js"
/* Loaded with SystemJS import */
var XLSX = require('xlsx');
_cb = function(evt) { /* ... do work here ... */ };
```
:::
</TabItem>
<TabItem value="nodejs" label="NodeJS">
:::caution
While SystemJS works in NodeJS, the built-in `require` should be preferred.
:::
The NodeJS module entrypoint is `xlsx/xlsx.js` and should be mapped:
```js
SystemJS.config({
map: {
"xlsx": "./node_modules/xlsx/xlsx.js"
}
});
```
The standalone scripts require a hint that the script assigns a global:
```js
SystemJS.config({
meta: {
"standalone": { format: "global" }
},
map: {
"standalone": "xlsx.full.min.js"
}
});
```
</TabItem>
</Tabs>
<details><summary><b>Complete Example</b> (click to show)</summary>
<Tabs>
<TabItem value="browser" label="Browser">
The [Live demo](pathname:///systemjs/systemjs.html) loads SystemJS from the
CDN, uses it to load the standalone script from the SheetJS CDN and emulate
a `require` implementation when loading [`main.js`](pathname:///systemjs/main.js)
"View Source" works on the main HTML page and the `main.js` script.
</TabItem>
<TabItem value="nodejs" label="NodeJS">
1) Install the dependencies:
<pre><code parentName="pre" {...{"className": "language-bash"}}>{`\
$ npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz systemjs@0.19`}
</code></pre>
2) Save the following script to `SheetJSystem.js`:
```js title="SheetJSystem.js"
const SystemJS = require('systemjs');
// highlight-start
SystemJS.config({
map: {
'xlsx': 'node_modules/xlsx/xlsx.js',
'fs': '@node/fs',
'crypto': '@node/crypto',
'stream': '@node/stream'
}
});
// highlight-end
SystemJS.import('xlsx').then(async function(XLSX) {
/* fetch JSON data and parse */
const url = "https://sheetjs.com/executive.json";
const raw_data = await (await fetch(url)).json();
/* filter for the Presidents */
const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez"));
/* flatten objects */
const rows = prez.map(row => ({
name: row.name.first + " " + row.name.last,
birthday: row.bio.birthday
}));
/* generate worksheet and workbook */
const worksheet = XLSX.utils.json_to_sheet(rows);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "Dates");
/* fix headers */
XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
/* calculate column width */
const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10);
worksheet["!cols"] = [ { wch: max_width } ];
/* create an XLSX file and try to save to Presidents.xlsx */
XLSX.writeFile(workbook, "Presidents.xlsx");
});
```
3) Run in NodeJS:
```bash
node SheetJSystem.js
```
If the demo worked, `Presidents.xlsx` will be created.
:::note
As it uses `fetch`, this demo requires Node 18.
:::
</TabItem>
</Tabs>
</details>
## Vite
:::caution

View File

@ -0,0 +1,129 @@
/* sheetjs (C) 2013-present SheetJS -- http://sheetjs.com */
/*jshint browser:true */
/*global XLSX */
var XLSX = require('xlsx');
var global_wb;
var process_wb = (function() {
var OUT = document.getElementById('out');
var HTMLOUT = document.getElementById('htmlout');
var get_format = (function() {
var radios = document.getElementsByName( "format" );
return function() {
for(var i = 0; i < radios.length; ++i) if(radios[i].checked || radios.length === 1) return radios[i].value;
};
})();
var to_json = function to_json(workbook) {
var result = {};
workbook.SheetNames.forEach(function(sheetName) {
var roa = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName]);
if(roa.length) result[sheetName] = roa;
});
return JSON.stringify(result, 2, 2);
};
var to_csv = function to_csv(workbook) {
var result = [];
workbook.SheetNames.forEach(function(sheetName) {
var csv = XLSX.utils.sheet_to_csv(workbook.Sheets[sheetName]);
if(csv.length){
result.push("SHEET: " + sheetName);
result.push("");
result.push(csv);
}
});
return result.join("\n");
};
var to_fmla = function to_fmla(workbook) {
var result = [];
workbook.SheetNames.forEach(function(sheetName) {
var formulae = XLSX.utils.get_formulae(workbook.Sheets[sheetName]);
if(formulae.length){
result.push("SHEET: " + sheetName);
result.push("");
result.push(formulae.join("\n"));
}
});
return result.join("\n");
};
var to_html = function to_html(workbook) {
HTMLOUT.innerHTML = "";
workbook.SheetNames.forEach(function(sheetName) {
var htmlstr = XLSX.write(workbook, {sheet:sheetName, type:'string', bookType:'html'});
HTMLOUT.innerHTML += htmlstr;
});
return "";
};
return function process_wb(wb) {
global_wb = wb;
var output = "";
switch(get_format()) {
case "form": output = to_fmla(wb); break;
case "html": output = to_html(wb); break;
case "json": output = to_json(wb); break;
default: output = to_csv(wb);
}
if(OUT.innerText === undefined) OUT.textContent = output;
else OUT.innerText = output;
if(typeof console !== 'undefined') console.log("output", new Date());
};
})();
var setfmt = window.setfmt = function setfmt() { if(global_wb) process_wb(global_wb); };
var b64it = window.b64it = (function() {
var tarea = document.getElementById('b64data');
return function b64it() {
if(typeof console !== 'undefined') console.log("onload", new Date());
var wb = XLSX.read(tarea.value, {type:'base64', WTF:false});
process_wb(wb);
};
})();
var do_file = (function() {
return function do_file(files) {
var f = files[0];
var reader = new FileReader();
reader.onload = function(e) {
if(typeof console !== 'undefined') console.log("onload", new Date());
var data = e.target.result;
data = new Uint8Array(data);
process_wb(XLSX.read(data, {type: 'array'}));
};
reader.readAsArrayBuffer(f);
};
})();
(function() {
var drop = document.getElementById('drop');
if(!drop.addEventListener) return;
function handleDrop(e) {
e.stopPropagation();
e.preventDefault();
do_file(e.dataTransfer.files);
}
function handleDragover(e) {
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
}
drop.addEventListener('dragenter', handleDragover, false);
drop.addEventListener('dragover', handleDragover, false);
drop.addEventListener('drop', handleDrop, false);
})();
(function() {
var xlf = document.getElementById('xlf');
if(!xlf.addEventListener) return;
function handleFile(e) { do_file(e.target.files); }
xlf.addEventListener('change', handleFile, false);
})();

View File

@ -0,0 +1,77 @@
<!DOCTYPE html>
<!-- sheetjs (C) 2013-present SheetJS http://sheetjs.com -->
<!-- vim: set ts=2: -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>SheetJS Live Demo</title>
<style>
#drop{
border:2px dashed #bbb;
-moz-border-radius:5px;
-webkit-border-radius:5px;
border-radius:5px;
padding:25px;
text-align:center;
font:20pt bold,"Vollkorn";color:#bbb
}
#b64data{
width:100%;
}
a { text-decoration: none }
</style>
</head>
<body>
<pre>
<b><a href="http://sheetjs.com">SheetJS Data Preview Live Demo</a></b>
(Base64 text works back to IE6; drag and drop works back to IE10)
<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a>
<a href="https://github.com/SheetJS/js-xlsx/issues">Issues? Something look weird? Click here and report an issue</a>
Output Format: <select name="format" onchange="setfmt()">
<option value="csv" selected> CSV</option>
<option value="json"> JSON</option>
<option value="form"> FORMULAE</option>
<option value="html"> HTML</option>
</select><br />
<div id="drop">Drop a spreadsheet file here to see sheet data</div>
<input type="file" name="xlfile" id="xlf" /> ... or click here to select a file
<textarea id="b64data">... or paste a base64-encoding here</textarea>
<input type="button" id="dotext" value="Click here to process the base64 text" onclick="b64it();"/><br />
<b>Advanced Demo Options:</b>
</pre>
<pre id="out"></pre>
<div id="htmlout"></div>
<br />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.20.16/system.js"></script>
<script>
SystemJS.config({
meta: {
'xlsx': {
exports: 'XLSX'
}
},
map: {
'xlsx': 'https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js',
'fs': '',
'crypto': '',
'stream': ''
}
});
SystemJS.import('main.js');
</script>
<script type="text/javascript">
/* eslint no-use-before-define:0 */
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-36810333-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>