NeutralinoJS
The Standalone build can be added
to the entry index.html
This demo was tested against "binaries" 4.7.0
and "client" 3.6.0
NeutralinoJS currently does not provide the equivalent of NodeJS fs
module.
The raw Neutralino.filesystem
and Neutralino.os
methods are used.
The os
and filesystem
modules must be enabled in neutralino.conf.json
.
The starter already enables os
so typically one line must be added:
"nativeAllowList": [
"app.*",
"os.*",
"filesystem.*",
"debug.log"
],
The "Complete Example" creates an app that looks like the screenshot:
At the time of writing, filters
did not work as expected on MacOS. They have
been omitted in the example and commented in the code snippets
Complete Example (click to show)
The app core state will be the HTML table. Reading files will add the table to the window. Writing files will parse the table into a spreadsheet.
1) Create a new NeutralinoJS app:
npx @neutralinojs/neu create sheetjs-neu
cd sheetjs-neu
2) Download the standalone script and place in resources/js/main.js
:
curl -L -o resources/js/xlsx.full.min.js https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js
3) Add the highlighted lines to neutralino.conf.json
in nativeAllowList
:
"nativeAllowList": [
"app.*",
"os.*",
"filesystem.*",
"debug.log"
],
4) Set up skeleton app and print version info:
- Edit
resources/index.html
and replace the<body>
with the code below:
<body>
<div id="neutralinoapp">
<h1>SheetJS × NeutralinoJS</h1>
<button onclick="importData()">Import Data</button>
<button onclick="exportData()">Export Data</button>
<div id="info"></div>
</div>
<script src="js/neutralino.js"></script>
<!-- Load the browser build and make XLSX available to main.js -->
<script src="js/xlsx.full.min.js"></script>
<script src="js/main.js"></script>
</body>
- Append the following code to
resources/styles.css
to center the table:
#info {
width:100%;
text-align: unset;
}
table {
margin: 0 auto;
}
- Print the version number in the
showInfo
method ofresources/js/main.js
:
${NL_APPID} is running on port ${NL_PORT} inside ${NL_OS}
<br/><br/>
<span>server: v${NL_VERSION} . client: v${NL_CVERSION}</span>
<br/><br/>
<span>SheetJS version ${XLSX.version}</span>
`;
5) Run the app:
npx @neutralinojs/neu run
You should see SheetJS Version
followed by the library version number.
6) Add the following code to the bottom of resources/js/main.js
:
(async() => {
const ab = await (await fetch("https://sheetjs.com/pres.numbers")).arrayBuffer();
const wb = XLSX.read(ab);
const ws = wb.Sheets[wb.SheetNames[0]];
document.getElementById('info').innerHTML = XLSX.utils.sheet_to_html(ws);
})();
Save the source file, close the app and re-run the command from step 5.
When the app loads, a table should show in the main screen.
7) Add importFile
and exportFile
to the bottom of resources/js/main.js
:
async function importData() {
/* show open dialog */
const [filename] = await Neutralino.os.showOpenDialog('Open a spreadsheet');
/* read data */
const ab = await Neutralino.filesystem.readBinaryFile(filename);
const wb = XLSX.read(ab);
/* make table */
const ws = wb.Sheets[wb.SheetNames[0]];
document.getElementById('info').innerHTML = XLSX.utils.sheet_to_html(ws);
}
async function exportData() {
/* show save dialog */
const filename = await Neutralino.os.showSaveDialog('Save to file');
/* make workbook */
const tbl = document.getElementById('info').querySelector("table");
const wb = XLSX.utils.table_to_book(tbl);
/* make file */
const bookType = filename.slice(filename.lastIndexOf(".") + 1);
const data = XLSX.write(wb, { bookType, type: "buffer" });
await Neutralino.filesystem.writeBinaryFile(filename, data);
}
Save the source file, close the app and re-run the command from step 5.
When the app loads, click the "Import File" button and select a spreadsheet to
see the contents. Click "Export File" and enter SheetJSNeu.xlsx
to write.
8) Build production apps:
npx @neutralinojs/neu run
Platform-specific programs will be created in the dist
folder.
Reading Files
There are two steps to reading files: obtaining a path and reading binary data:
const filters = [
{name: "Excel Binary Workbook", extensions: ["xlsb"]},
{name: "Excel Workbook", extensions: ["xlsx"]},
]
async function openFile() {
/* show open file dialog */
const [filename] = await Neutralino.os.showOpenDialog(
'Open a spreadsheet',
{ /* filters, */ multiSelections: false }
);
/* read data into an ArrayBuffer */
const ab = await Neutralino.filesystem.readBinaryFile(filename);
/* parse with SheetJS */
const wb = XLSX.read(ab);
return wb;
}
This method can be called from a button click or other event.
Writing Files
There are two steps to writing files: obtaining a path and writing binary data:
const filters = [
{name: "Excel Binary Workbook", extensions: ["xlsb"]},
{name: "Excel Workbook", extensions: ["xlsx"]},
]
async function saveFile(wb) {
/* show save file dialog */
const filename = await Neutralino.os.showSaveDialog(
'Save to file',
{ /* filters */ }
);
/* Generate workbook */
const bookType = filename.slice(filename.lastIndexOf(".") + 1);
const data = XLSX.write(wb, { bookType, type: "buffer" });
/* save data to file */
await Neutralino.filesystem.writeBinaryFile(filename, data);
}