Electron 项目实现下载文件监听

Electron 项目实现下载文件监听

随着现代应用程序功能的不断扩展,用户对下载文件的需求也越来越高。特别是在 Electron 应用程序中,提供一个高效、可靠的下载管理功能是提升用户体验的

关键之一。本文将详细介绍如何在 Electron 项目中实现下载文件的监控,包括进度信息的实时更新,并将这些信息返回给前端。同时,还会讲解如何避免用户点击下载按钮时弹出下载对话框,

直接下载到设置的默认路径。本文将为你提供详细的步骤和代码示例,帮助你快速实现这一功能。

目标
  1. 实现下载文件的监听,包括下载进度和最终状态。
  2. 将下载详细信息发送到前端并实时显示。
  3. 避免用户点击下载按钮时弹出下载对话框,直接下载到设置的默认路径。
步骤
  1. 设置项目环境
  2. 创建主窗口
  3. 监听下载事件
  4. 发送下载状态到前端
  5. 前端接收并显示下载状态
  6. 避免弹出下载对话框

1. 设置项目环境

首先,确保你已经安装了 Electron。如果还没有安装,可以使用以下命令进行安装:

bash 复制代码
npm install electron --save-dev

2. 创建主窗口

在项目的主文件(通常是 main.js)中,创建主窗口并加载前端页面。

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

let mainWindow;

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

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

app.on('ready', async () => {
    await createWindow();
});

3. 监听下载事件

main.js 中,监听 will-download 事件,设置默认下载路径,并监控下载状态。

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

let mainWindow;

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

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

app.on('ready', async () => {
    await createWindow();

    let session = mainWindow.webContents.session;

    session.on('will-download', (event, item, webContents) => {
        // 获取当前用户的下载文件夹路径
        const defaultDownloadPath = app.getPath('downloads');
        const suggestedFileName = item.getFilename();
        const savePath = path.join(defaultDownloadPath, suggestedFileName);

        // 设置下载项的保存路径
        item.setSavePath(savePath);

        // 发送下载开始信息到前端
        mainWindow.webContents.send('download-started', { filename: suggestedFileName, savePath });

        // 初始化已接收字节数
        let receivedBytes = 0;

        // 监听下载进度
        item.on('updated', (event, state) => {
            if (state === 'interrupted') {
                mainWindow.webContents.send('download-interrupted', { filename: suggestedFileName });
            } else if (state === 'progressing') {
                if (item.isPaused()) {
                    mainWindow.webContents.send('download-paused', { filename: suggestedFileName });
                } else {
                    receivedBytes = item.getReceivedBytes();
                    let progress = Math.round((receivedBytes / item.getTotalBytes()) * 100);
                    mainWindow.webContents.send('download-progress', { filename: suggestedFileName, progress });
                }
            }
        });

        // 监听下载完成
        item.once('done', (event, state) => {
            if (state === 'completed') {
                mainWindow.webContents.send('download-completed', { filename: suggestedFileName, savePath });
            } else {
                mainWindow.webContents.send('download-failed', { filename: suggestedFileName, error: state });
            }
        });
    });
});

4. 发送下载状态到前端

在上面的代码中,我们使用 mainWindow.webContents.send 方法将下载状态发送到前端。这些状态包括下载开始、下载进度、下载中断、下载暂停和下载完成。

5. 前端接收并显示下载状态

在前端页面(通常是 index.html)中,使用 Electron 的 ipcRenderer 模块接收这些状态并显示。

index.html
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Electron Download Monitor</title>
    <style>
        body {
            font-family: Arial, sans-serif;
        }
        .download-status {
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <h1>Electron Download Monitor</h1>
    <button id="download-button">开始下载</button>
    <div id="download-status" class="download-status"></div>

    <script src="renderer.js"></script>
</body>
</html>
renderer.js
javascript 复制代码
const { ipcRenderer } = require('electron');

document.getElementById('download-button').addEventListener('click', () => {
    // 触发下载操作
    ipcRenderer.send('start-download');
});

// 监听下载开始事件
ipcRenderer.on('download-started', (event, data) => {
    const statusDiv = document.getElementById('download-status');
    statusDiv.innerHTML += `<p>下载开始: ${data.filename} 到 ${data.savePath}</p>`;
});

// 监听下载进度事件
ipcRenderer.on('download-progress', (event, data) => {
    const statusDiv = document.getElementById('download-status');
    statusDiv.innerHTML += `<p>下载进度: ${data.filename} - ${data.progress}%</p>`;
});

// 监听下载中断事件
ipcRenderer.on('download-interrupted', (event, data) => {
    const statusDiv = document.getElementById('download-status');
    statusDiv.innerHTML += `<p>下载中断: ${data.filename}</p>`;
});

// 监听下载暂停事件
ipcRenderer.on('download-paused', (event, data) => {
    const statusDiv = document.getElementById('download-status');
    statusDiv.innerHTML += `<p>下载暂停: ${data.filename}</p>`;
});

// 监听下载完成事件
ipcRenderer.on('download-completed', (event, data) => {
    const statusDiv = document.getElementById('download-status');
    statusDiv.innerHTML += `<p>下载完成: ${data.filename} 保存到 ${data.savePath}</p>`;
});

// 监听下载失败事件
ipcRenderer.on('download-failed', (event, data) => {
    const statusDiv = document.getElementById('download-status');
    statusDiv.innerHTML += `<p>下载失败: ${data.filename} - 错误: ${data.error}</p>`;
});

6. 避免弹出下载对话框

在上面的代码中,我们已经在 will-download 事件的回调函数中设置了默认下载路径,从而避免弹出下载对话框。具体代码如下:

javascript 复制代码
session.on('will-download', (event, item, webContents) => {
    // 获取当前用户的下载文件夹路径
    const defaultDownloadPath = app.getPath('downloads');
    const suggestedFileName = item.getFilename();
    const savePath = path.join(defaultDownloadPath, suggestedFileName);

    // 设置下载项的保存路径
    item.setSavePath(savePath);

    // 发送下载开始信息到前端
    mainWindow.webContents.send('download-started', { filename: suggestedFileName, savePath });

    // 初始化已接收字节数
    let receivedBytes = 0;

    // 监听下载进度
    item.on('updated', (event, state) => {
        if (state === 'interrupted') {
            mainWindow.webContents.send('download-interrupted', { filename: suggestedFileName });
        } else if (state === 'progressing') {
            if (item.isPaused()) {
                mainWindow.webContents.send('download-paused', { filename: suggestedFileName });
            } else {
                receivedBytes = item.getReceivedBytes();
                let progress = Math.round((receivedBytes / item.getTotalBytes()) * 100);
                mainWindow.webContents.send('download-progress', { filename: suggestedFileName, progress });
            }
        }
    });

    // 监听下载完成
    item.once('done', (event, state) => {
        if (state === 'completed') {
            mainWindow.webContents.send('download-completed', { filename: suggestedFileName, savePath });
        } else {
            mainWindow.webContents.send('download-failed', { filename: suggestedFileName, error: state });
        }
    });
});

总结

通过以上步骤,你可以在 Electron 项目中实现下载文件的监控,并将下载状态(包括进度信息)返回给前端。这样,用户可以实时看到下载的进度和结果。从设置项目环境到监听下载事件,再到将下载状态发送到前端并实时显示,每一步都经过详细讲解和代码示例展示。此外,还讲解了如何避免用户点击下载按钮时弹出下载对话框,直接下载到设置的默认路径。

相关推荐
NightCyberpunk31 分钟前
JavaScript学习笔记
javascript·笔记·学习
北极糊的狐34 分钟前
vue使用List.forEach遍历集合元素
前端·javascript·vue.js
老码沉思录1 小时前
React Native 全栈开发实战班 - 性能与调试之内存管理
javascript·react native·react.js
ZVAyIVqt0UFji1 小时前
Reactflow图形库结合Dagre算法实现函数资源关系图
开发语言·前端·javascript·ecmascript
cooldream20092 小时前
快速上手 Vue 3 的高效组件库Element Plus
前端·javascript·vue.js·element plus
疯狂的沙粒2 小时前
Vue项目开发 vue实例挂载的过程?
前端·javascript·vue.js
zxg_神说要有光3 小时前
快速入门 AI:调用 AI 接口生成 React 组件
前端·javascript·node.js
佚名程序员3 小时前
【Node.js】深入理解 V8 JavaScript 引擎
前端·javascript·node.js
最近好乐3 小时前
TS入门——快速上手(一)
前端·javascript·面试
小粉粉hhh3 小时前
CSS3新特性——字体图标、2D、3D变换、过渡、动画、多列布局
前端·javascript·html