web-dev-qa-db-ja.com

Electronアプリで[名前を付けて保存]ダイアログを表示するにはどうすればよいですか?

すべてのプラットフォームで配布されるNodeJS Electronアプリを書いています。サーバーから提供されているファイルを使用して[名前を付けて保存]ダイアログを開きたいダウンロードボタンがあります。誰かがこれを行う最善の方法を知っていますか?

これは、ノードアプリをローカルで実行しているときに試してみましたが、electron-packagerでアプリをパッケージ化した後で失敗しました。

  • Window.location.hrefをファイルの場所に設定する
  • 非表示のiframeのソースをファイルの場所に設定する

パッケージ化されたMacアプリを実行すると、「did-fail-load」イベントが発生し、[名前を付けて保存]ダイアログが表示されなくなります。ネットワークリクエストを見ると、ファイルがサーバーから正常に取得されていることがわかります。 「did-fail-load」イベントが発生している理由がわかりません。

12
djsosofresh

Electron docsでこのページを見てください 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

7
user3580864

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);
    });
};
2
bob