SheetJS / sheetjs

📗 SheetJS Spreadsheet Data Toolkit -- New home https://git.sheetjs.com/SheetJS/sheetjs
https://sheetjs.com/
Apache License 2.0
35.04k stars 8k forks source link

Unable to write .xls file in ^0.18.3, works in ^0.17.0 #2540

Closed dlackey closed 2 years ago

dlackey commented 2 years ago

Writing file with an array of simple objects in an electron environment. Rolled back to ^0.17.0 and it works again.

path ends in .xls

function writeWorkbook(data, path) {
  // Create workbook
  const workbook = xlsx.utils.book_new();
  const worksheet = xlsx.utils.json_to_sheet(data);
  xlsx.utils.book_append_sheet(workbook, worksheet);

  // Write file
  xlsx.writeFile(workbook, path);
}
reviewher commented 2 years ago

Is there an error message? So we can reproduce, what version of electron?

SheetJSDev commented 2 years ago

Can you check the electron demo ?

As it currently stands, it appears to work correctly in Electron 9.0.5 and Electron 13.6.9. To verify, do a fresh clone and install the dependencies:

$ git clone --depth=1 https://github.com/sheetjs/sheetjs/
$ cd sheetjs/demos/electron/
$ mkdir -p node_modules
$ npm i xlsx electron@9.0.5
$ npx electron --version
v9.0.5
$ npx electron .

Once open, drop some file, then hit "Export data" and enter the name "Untitled.xls" in the popup.

This also works in electron 13:

$ npm i xlsx electron@13.x
$ npx electron --version
v13.6.9
$ npx electron .

In Electron v14.2.6, the demo throws an error because remote was actually removed, but that can be resolved by installing @electron/remote and applying the patch:

diff --git a/demos/electron/index.js b/demos/electron/index.js
@@ -1,6 +1,6 @@
 /* xlsx.js (C) 2013-present SheetJS -- https://sheetjs.com */
 const XLSX = require('xlsx');
-const electron = require('electron').remote;
+const electron = require('@electron/remote');

 const EXTENSIONS = "xls|xlsx|xlsm|xlsb|xml|csv|txt|dif|sylk|slk|prn|ods|fods|htm|html".split("|");
 diff --git a/demos/electron/main.js b/demos/electron/main.js
@@ -3,6 +3,7 @@
 var electron = require('electron');
 var XLSX = require('xlsx');
 var app = electron.app;
+require('@electron/remote/main').initialize();

 var win = null;

@@ -18,6 +19,7 @@ function createWindow() {
                }
        });
        win.loadURL("file://" + __dirname + "/index.html");
+       require('@electron/remote/main').enable(win.webContents);
        win.webContents.openDevTools();
        win.on('closed', function () { win = null; });
 }

The same patch appears to work for v15.4.0, v16.0.10 and v17.1.0, so the demo probably should be updated

dlackey commented 2 years ago

Is there an error message? So we can reproduce, what version of electron?

Sorry for not adding more information. Callstack and dependencies below.

Error occurred in handler for 'save-xls-file': Error: cannot save file /var/folders/8d/_9ptghps5579123msc40000gn/T/xls-file.xls
    at write_dl (/Users/user/Git/repository/.webpack/main/index.js:471899:8)
    at write_cfb_ctr (/Users/user/Git/repository/.webpack/main/index.js:492118:23)
    at write_cfb_type (/Users/user/Git/repository/.webpack/main/index.js:492166:9)
    at writeSync (/Users/user/Git/repository/.webpack/main/index.js:492254:46)
    at Module.writeFileSync (/Users/user/Git/repository/.webpack/main/index.js:492282:9)
    at writeWorkbook (/Users/user/Git/repository/.webpack/main/index.js:463310:8)
    at parseData (/Users/user/Git/repository/.webpack/main/index.js:463672:3)
    at /Users/user/Git/repository/.webpack/main/index.js:463290:53
    at node:electron/js2c/browser_init:193:579
    at EventEmitter.<anonymous> (node:electron/js2c/browser_init:161:10433)
  "dependencies": {
    "@emotion/styled": "^11.8.1",
    "@fontsource/roboto": "^4.5.3",
    "@mui/icons-material": "^5.4.2",
    "@mui/material": "^5.4.3",
    "googleapis": "^95.0.0",
    "luxon": "^2.3.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "xlsx": "^0.18.3"
  },
  "devDependencies": {
    "@babel/core": "^7.17.5",
    "@babel/preset-react": "^7.16.7",
    "@electron-forge/cli": "^6.0.0-beta.63",
    "@electron-forge/plugin-webpack": "^6.0.0-beta.63",
    "@vercel/webpack-asset-relocator-loader": "^1.7.0",
    "babel-loader": "^8.2.3",
    "css-loader": "^6.6.0",
    "electron": "17.1.0",
    "jest": "^27.5.1",
    "node-loader": "^2.0.0",
    "style-loader": "^3.3.1"
  }
reviewher commented 2 years ago

Does the electron demo work?

dlackey commented 2 years ago

Does the electron demo work?

The electron demo works for electron version ^17.1.0 after applying the patch. I am able to drop and export successfully.

reviewher commented 2 years ago

Electron demo does some special stuff:

preferences:

        webPreferences: {
            worldSafeExecuteJavaScript: true, // required for Electron 12+
            contextIsolation: false, // required for Electron 12+
            nodeIntegration: true,
            enableRemoteModule: true
        }

showing a dialog before saving:

    const o = await electron.dialog.showSaveDialog({
        title: 'Save file as',
        filters: [{
            name: "Spreadsheets",
            extensions: EXTENSIONS
        }]
    });
    console.log(o.filePath);
    XLSX.writeFile(wb, o.filePath);

Copy these parts into your project, and if you still have problems please follow up with the Electron project.

dlackey commented 2 years ago

Thank you so much for the help on this!