第7章:Electron文件系统操作(2)

7.2 文件对话框

Electron 提供了 dialog 模块用于显示文件打开和保存对话框。

7.2.1 显示文件打开对话框

主进程代码:

javascript 复制代码
const { app, BrowserWindow, ipcMain, dialog } = require('electron');
const path = require('path');

let mainWindow;

const createMainWindow = () => {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      contextIsolation: true,
      nodeIntegration: false
    }
  });

  mainWindow.loadFile('index.html');
  mainWindow.webContents.openDevTools();
  mainWindow.on('closed', () => {
    mainWindow = null;
  });
};

app.on('ready', createMainWindow);
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});
app.on('activate', () => {
  if (mainWindow === null) {
    createMainWindow();
  }
});

// 处理文件打开对话框请求
ipcMain.handle('open-file-dialog', async () => {
  const result = await dialog.showOpenDialog({
    properties: ['openFile']
  });
  if (result.canceled) {
    return { success: false };
  } else {
    return { success: true, filePaths: result.filePaths };
  }
});

预加载脚本(preload.js):

javascript 复制代码
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electronAPI', {
  openFileDialog: () => ipcRenderer.invoke('open-file-dialog')
});

渲染进程代码:

html 复制代码
<!DOCTYPE html>
<html>
<head>
  <title>File Dialog Example</title>
</head>
<body>
  <h1>Open File Dialog Example</h1>
  <button id="openFileDialog">Open File</button>
  <p id="filePath"></p>

  <script>
    document.getElementById('openFileDialog').addEventListener('click', async () => {
      const result = await window.electronAPI.openFileDialog();
      if (result.success) {
        document.getElementById('filePath').innerText = 'Selected file: ' + result.filePaths[0];
      } else {
        document.getElementById('filePath').innerText = 'No file selected';
      }
    });
  </script>
</body>
</html>

7.2.2 显示文件保存对话框

主进程代码:

javascript 复制代码
const { app, BrowserWindow, dialog } = require("electron");
const { ipcMain } = require("electron");

let mainWindow;

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: true,
      preload: __dirname + "/preload.js",
    },
  });

  mainWindow.loadFile("index.html");
}

app.whenReady().then(() => {
  createWindow();

  app.on("activate", function () {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });

  // 添加ipcMain.handle处理来自渲染进程的save-file请求
  ipcMain.handle("save-file", async (event, options) => {
    try {
      const result = await dialog.showSaveDialog(mainWindow, options);
      return result.filePath; // 直接返回文件路径给renderer,无需额外的reply
    } catch (err) {
      console.error("Error showing save dialog:", err);
      throw err;
    }
  });
});

app.on("window-all-closed", function () {
  if (process.platform !== "darwin") app.quit();
});

预加载脚本(preload.js):

javascript 复制代码
const { contextBridge, ipcRenderer } = require("electron");

// 在preload中暴露安全的API给渲染进程
contextBridge.exposeInMainWorld("api", {
  saveFile: (options) => {
    return ipcRenderer.invoke("save-file", options);
  },
});

渲染进程代码:

javascript 复制代码
document.getElementById("saveButton").addEventListener("click", async () => {
  const options = {
    title: "Save your File",
    defaultPath: "untitled.txt",
    filters: [
      { name: "Text Files", extensions: ["txt"] },
      { name: "All Files", extensions: ["*"] },
    ],
  };

  try {
    const filePath = await window.api.saveFile(options);
    if (filePath) {
      console.log(`File will be saved at: ${filePath}`);
      // 这里可以添加保存文件的具体逻辑
    } else {
      console.log("User canceled the save operation.");
    }
  } catch (error) {
    console.error("Error during file save operation:", error);
  }
});

HTML代码:

html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Save File Example</title>
  </head>
  <body>
    <h1>Click to Save a File</h1>
    <button id="saveButton">Save File</button>

    <script src="./renderer.js"></script>
  </body>
</html>
相关推荐
对空六课1 小时前
两个统计平台数据不同:用同一时间窗和事件样本做差异定位
大数据·前端·网络·数据库
lpfasd1239 小时前
node-sass 停止维护!老项目迁移 Dart Sass 完整教程
前端·rust·sass
Data analyse45611 小时前
rnweb 回放数据量太大怎么办?分片存储与断点续传的实现思路
前端·网络·算法·数据分析
xiaogai_gai11 小时前
金蝶收料通知单查询策略实战教程:从源系统拉取到中间层落地的完整路径
java·前端·数据库
环境栈笔记12 小时前
指纹浏览器 WebRTC 怎么设置?从 ICE 候选、代理出口到功能验证
前端·人工智能·后端·自动化
赵大仁13 小时前
官网性能优化实战:LCP 3.2s → 2.1s、CLS 0.107 → 0,以及被我推翻的 6 个判断
前端·性能优化·cls·lcp·core web vitals
xiancai_xianyu13 小时前
Text2SQL落地生产库前,SQL要过哪三道闸
前端·数据库·sql·sql注入·text2sql·ai agent开发·企业级ai框架
小羊没烦恼!13 小时前
T-SQL查询进阶--理解SQL SERVER中的分区表
服务器·开发语言·前端·javascript·html
史瓦辛格13 小时前
给 DeepSeek Harness 写费用插件:把「这次会话花了多少钱」算准
前端·deepseek
星光不问赶路人13 小时前
Vue 3 + TypeScript 中 enum 的使用实践
前端·vue.js