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

相关推荐
it_remember2 小时前
新建一个reactnative 0.72.0的项目
javascript·react native·react.js
敲代码的小吉米3 小时前
前端上传el-upload、原生input本地文件pdf格式(纯前端预览本地文件不走后端接口)
前端·javascript·pdf·状态模式
da-peng-song3 小时前
ArcGIS Desktop使用入门(二)常用工具条——数据框工具(旋转视图)
开发语言·javascript·arcgis
低代码布道师4 小时前
第五部分:第一节 - Node.js 简介与环境:让 JavaScript 走进厨房
开发语言·javascript·node.js
满怀10155 小时前
【Vue 3全栈实战】从响应式原理到企业级架构设计
前端·javascript·vue.js·vue
伟笑5 小时前
elementUI 循环出来的表单,怎么做表单校验?
前端·javascript·elementui
确实菜,真的爱6 小时前
electron进程通信
前端·javascript·electron
小赵面校招6 小时前
基于Session实现短信登录全流程详解
状态模式
魔术师ID7 小时前
vue 指令
前端·javascript·vue.js
Clown958 小时前
Go语言爬虫系列教程 实战项目JS逆向实现CSDN文章导出教程
javascript·爬虫·golang