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

相关推荐
Dread_lxy15 分钟前
vue 依赖注入(Provide、Inject )和混入(mixins)
前端·javascript·vue.js
奔跑草-1 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
羡与1 小时前
echarts-gl 3D柱状图配置
前端·javascript·echarts
前端郭德纲2 小时前
浏览器是加载ES6模块的?
javascript·算法
JerryXZR2 小时前
JavaScript核心编程 - 原型链 作用域 与 执行上下文
开发语言·javascript·原型模式
帅帅哥的兜兜2 小时前
CSS:导航栏三角箭头
javascript·css3
渗透测试老鸟-九青2 小时前
通过投毒Bingbot索引挖掘必应中的存储型XSS
服务器·前端·javascript·安全·web安全·缓存·xss
龙猫蓝图2 小时前
vue el-date-picker 日期选择器禁用失效问题
前端·javascript·vue.js
夜色呦2 小时前
掌握ECMAScript模块化:构建高效JavaScript应用
前端·javascript·ecmascript
peachSoda72 小时前
随手记:简单实现纯前端文件导出(XLSX)
前端·javascript·vue.js