【问题标题】:How can I display a Save As dialog in an Electron App?如何在电子应用程序中显示另存为对话框?
【发布时间】:2016-01-03 22:35:21
【问题描述】:

我正在编写一个要在所有平台上分发的 NodeJS Electron 应用程序。我有一个下载按钮,我想弹出一个“另存为”对话框,其中包含从服务器提供的文件。有人知道最好的方法吗?

以下是我在本地运行节点应用程序时尝试过的工作,但在我使用电子打包程序打包应用程序后失败:

  • 将 window.location.href 设置为文件的位置
  • 将隐藏 iframe 的 src 设置为文件的位置

运行打包的 mac 应用程序时,会触发“did-fail-load”事件并阻止“另存为”对话框显示。查看网络请求时,我可以看到文件已从服务器成功检索。我似乎无法弄清楚为什么会触发“did-fail-load”事件。

【问题讨论】:

    标签: node.js electron


    【解决方案1】:

    查看电子文档https://github.com/atom/electron/blob/master/docs/api/dialog.md上的此页面

    有一段关于dialog.showSaveDialog

    然后,您可以使用保存对话框中的 URL 并使用类似于下面的功能将其保存到该位置。

    session.on('will-download', function(event, item, webContents) {
      event.preventDefault();
      require('request')(item.getUrl(), function(data) {
        require('fs').writeFileSync('/somewhere', data);
      });
    });
    

    在此页面上找到https://github.com/atom/electron/blob/master/docs/api/session.md

    【讨论】:

    • 感谢您的回答。我无法让这种方法发挥作用。我认为我在主进程与渲染器进程中需要库时遇到了问题。在我杀死所有节点模块并重新安装它们之后,我的原始方法奏效了。不确定到底是什么导致了这个问题,但现在可以工作了!
    【解决方案2】:

    在 HTML 按钮上:

    <button onclick='myUrlSaveAs("http://www.example.com/path/to/file.jpg")'>Save As</button>
    

    在您的 javascript 文件中:

    // Include in the render side
    var elerem = require('electron').remote;
    var dialog = elerem.dialog;
    var app = elerem.app;
    
    var http = require('http');
    var fs = require('fs');
    var path = require('path');
    
    
    function myUrlSaveAs(remoteUrl){
        // app.getPath("desktop")       // User's Desktop folder
        // app.getPath("documents")     // User's "My Documents" folder
        // app.getPath("downloads")     // User's Downloads folder
    
        var toLocalPath = path.resolve(app.getPath("desktop"), path.basename(remoteUrl) 
    
        var userChosenPath = dialog.showSaveDialog({ defaultPath: toLocalPath });
    
        if(userChosenPath){
            download (remoteUrl, userChosenPath, myUrlSaveAsComplete)
        }
    
    
    }
    
    function myUrlSaveAsComplete(err){
        alert("done");
    }
    
    
    function download (url, dest, cb) {
        var file = fs.createWriteStream(dest);
        var request = http.get(url, function(response) {
            response.pipe(file);
            file.on('finish', function() {
                file.close(cb); // close() is async, call cb after close completes.
            });
        }).on('error', function(err) { // Handle errors
            fs.unlink(dest); // Delete the file async. (But we don't check the result)
            if (cb) cb(err.message);
        });
    };
    

    【讨论】:

    • 从我尝试过的所有帖子中,这是唯一对我有用的帖子!谢谢
    【解决方案3】:

    如果您只想使用渲染器,下面是一个示例。单击时,Electron 将显示标准浏览器的另存为对话框。不需要remote 也不需要fs

    <!--html-->
    <button onclick="saveFile()">SAVE AS</button>
    

    在渲染器 javascript 文件中:

    // renderer javascript file
    function saveFile() {
        const content = "File content to save";
        const element = document.createElement("a");
        const file = new Blob([content], {type: "text/plain"});
        element.href = URL.createObjectURL(file);
        element.download = "file.txt";
        element.click();
    }
    

    (我在 mac 上,还没有在 Windows 机器上尝试过)

    【讨论】:

    • 完美.. 刚刚用这个 sn-p 替换了我的 filesaver.js 代码。它在Firefox和电子中工作。完美!
    猜你喜欢
    • 2022-09-25
    • 2011-08-03
    • 2018-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 1970-01-01
    相关资源
    最近更新 更多