forked from sheetjs/docs.sheetjs.com
feat: [Electron Demo] - implement OS level file associations via dist build.
This commit is contained in:
parent
93de5bce80
commit
d1efa326f6
@ -1,5 +1,6 @@
|
||||
const XLSX = require("xlsx");
|
||||
const electron = require("@electron/remote");
|
||||
const { ipcRenderer } = require('electron');
|
||||
|
||||
// --- Supported Extensions ---
|
||||
const EXTENSIONS =
|
||||
@ -202,3 +203,16 @@ async function readFile(files) {
|
||||
|
||||
// --- Initial Setup ---
|
||||
attachDropListeners();
|
||||
|
||||
// handle file opening events from the main process
|
||||
ipcRenderer.on('file-opened', async (_evt, filePath) => {
|
||||
console.log('Received file-opened event:', filePath);
|
||||
showSpinner();
|
||||
// yield to event loop to render spinner
|
||||
await new Promise(r => setTimeout(r, 50));
|
||||
renderWorkbookToTables(XLSX.readFile(filePath)); // already in your helper list
|
||||
showLoadedFileUI(filePath.split(/[/\\]/).pop());
|
||||
hideSpinner();
|
||||
hideDropUI();
|
||||
showExportBtn();
|
||||
});
|
@ -6,6 +6,57 @@ require('@electron/remote/main').initialize(); // required for Electron 14+
|
||||
|
||||
var win = null;
|
||||
|
||||
const EXT_REGEX = /\.(xls|xlsx|xlsm|xlsb|xml|csv|txt|dif|sylk|slk|prn|ods|fods|htm|html|numbers)$/i;
|
||||
const pendingPaths = []; // any paths that arrive before the window exists
|
||||
|
||||
|
||||
// send file opening events to renderer
|
||||
function sendToRenderer(filePath) {
|
||||
if (win && win.webContents) {
|
||||
win.webContents.send('file-opened', filePath);
|
||||
} else {
|
||||
pendingPaths.push(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
function firstSpreadsheetFromArgv() {
|
||||
const args = process.defaultApp // dev: electron .
|
||||
? process.argv.slice(2) // skip electron executable & dir
|
||||
: process.argv.slice(1); // skip packaged exe
|
||||
return args.find(a => EXT_REGEX.test(a)); // undefined if none
|
||||
}
|
||||
|
||||
/* ---- 1️⃣ single-instance guard (needed for Windows / Linux) ---- */
|
||||
// on windows and linux, opening a file opens a new instance of the app, this prevents that.
|
||||
const gotLock = app.requestSingleInstanceLock();
|
||||
if (!gotLock) app.quit();
|
||||
else {
|
||||
app.on('second-instance', (_e, argv) => { // emitted in *primary* instance
|
||||
const fp = argv.find(a => EXT_REGEX.test(a));
|
||||
if (fp) sendToRenderer(fp);
|
||||
if (win) { win.show(); win.focus(); }
|
||||
});
|
||||
}
|
||||
|
||||
/* ---- 2️⃣ platform-specific “open file” hooks ---- */
|
||||
app.on('open-file', (event, fp) => { // macOS Dock / Finder
|
||||
event.preventDefault();
|
||||
sendToRenderer(fp);
|
||||
});
|
||||
|
||||
app.on('open-url', (event, url) => { // you can add a custom protocol if you want to handle URLs
|
||||
event.preventDefault();
|
||||
sendToRenderer(url.replace('file://', '')); // crude, adjust if you keep deep-links
|
||||
});
|
||||
|
||||
/* ---- 3️⃣ normal start-up, harvest argv ---- */
|
||||
app.whenReady().then(() => {
|
||||
const fp = firstSpreadsheetFromArgv(); // Windows & Linux first launch
|
||||
if (fp) pendingPaths.push(fp);
|
||||
createWindow();
|
||||
});
|
||||
|
||||
/* ---- 4️⃣ create the window ---- */
|
||||
function createWindow() {
|
||||
if (win) return;
|
||||
win = new electron.BrowserWindow({
|
||||
@ -18,12 +69,15 @@ function createWindow() {
|
||||
}
|
||||
});
|
||||
win.loadURL("file://" + __dirname + "/index.html");
|
||||
require('@electron/remote/main').enable(win.webContents); // required for Electron 14+
|
||||
win.webContents.openDevTools();
|
||||
require('@electron/remote/main').enable(win.webContents); // required for Electron 14
|
||||
if (process.env.NODE_ENV === 'development') win.webContents.openDevTools(); // only open devtools in development
|
||||
win.on('closed', function () { win = null; });
|
||||
win.webContents.once('did-finish-load', () => {
|
||||
pendingPaths.splice(0).forEach(sendToRenderer);
|
||||
});
|
||||
}
|
||||
if (app.setAboutPanelOptions) app.setAboutPanelOptions({ applicationName: 'sheetjs-electron', applicationVersion: "XLSX " + XLSX.version, copyright: "(C) 2017-present SheetJS LLC" });
|
||||
app.on('open-file', function () { console.log(arguments); });
|
||||
|
||||
app.on('ready', createWindow);
|
||||
app.on('activate', createWindow);
|
||||
app.on('window-all-closed', function () { if (process.platform !== 'darwin') app.quit(); });
|
||||
|
@ -12,7 +12,8 @@
|
||||
"scripts": {
|
||||
"start": "electron-forge start",
|
||||
"package": "electron-forge package",
|
||||
"make": "electron-forge make"
|
||||
"make": "electron-forge make",
|
||||
"dist": "electron-builder"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron-forge/cli": "7.8.0",
|
||||
@ -20,8 +21,28 @@
|
||||
"@electron-forge/maker-rpm": "7.8.0",
|
||||
"@electron-forge/maker-squirrel": "7.8.0",
|
||||
"@electron-forge/maker-zip": "7.8.0",
|
||||
"electron": "35.1.2"
|
||||
"electron": "35.1.2",
|
||||
"electron-builder": "^26.0.12"
|
||||
},
|
||||
|
||||
"build": {
|
||||
"appId": "com.sheetjs.electron",
|
||||
"fileAssociations": [
|
||||
{
|
||||
"ext": [
|
||||
"xls","xlsx","xlsm","xlsb","xml","csv","txt","dif",
|
||||
"sylk","slk","prn","ods","fods","htm","html","numbers"
|
||||
],
|
||||
"name": "Spreadsheet / Delimited File",
|
||||
"description": "Spreadsheets and delimited text files opened by SheetJS-Electron",
|
||||
"role": "Editor"
|
||||
}
|
||||
],
|
||||
"mac": { "target": "dmg" },
|
||||
"win": { "target": "nsis" },
|
||||
"linux": { "target": "deb" }
|
||||
},
|
||||
|
||||
"config": {
|
||||
"forge": {
|
||||
"packagerConfig": {},
|
||||
|
@ -288,6 +288,7 @@ summary:focus-within {
|
||||
.sheetjs-tab-content {
|
||||
cursor: pointer;
|
||||
padding: 1rem;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
/* =====================
|
||||
|
Loading…
Reference in New Issue
Block a user