LoginSignup
39
45

More than 5 years have passed since last update.

ElectronでFileのOpenとSave

Posted at

Electronでファイル操作する必要があったのでOpenとSaveの方法をメモ。

dialogの制御方法が知りたいのが主目的なので、ロジックはなし。
csvを読み込み表示。そのままsaveする。

仕様

下記のような感じ。

  • openボタンを押すとファイオープンし、textareaに表示。
  • saveでtextarea内の内容をfileにSave。

スクリーンショット 2019-01-27 7.14.03.png

textarea内を変更しても内容はファイルには反映されない。それをやるにはVueとかReact使う。

実装

package.json

エンドポイントはmain.jsとしました。

package.json
{
  "name": "openclose",
  "version": "1.0.0",
  "description": "sample",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "devDependencies": {
    "electron": "^4.0.2"
  }
}

main.js

ElectronのQuick Startのmain.jsとほぼ一緒。
起動時の表示としてindex.htmlを呼び出している。

main.js
const { app, BrowserWindow } = require('electron')

let win

function createWindow() {

    //ウインドウの作成
    win = new BrowserWindow({ width: 800, height: 400 })

    //ウインドウに表示する内容
    win.loadFile('index.html')

    //デバッグ画面表示
    // win.webContents.openDevTools()

    //このウインドウが閉じられたときの処理
    win.on('closed', () => {
        win = null
    })
}

//アプリが初期化されたとき(起動されたとき)
app.on('ready', () => {
    createWindow()
})

//全ウインドウが閉じられたとき
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit()
    }
})

//アクティブになったとき(MacだとDockがクリックされたとき)
app.on('activate', () => {
    if (win === null) {
        createWindow()
    }
})

index.html

画面要素を配置。ロジックを実装するindex.jsとstyles.cssを呼び出している。

index.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>sample</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h3>File Open/Save</h3>
    <button id="openFile">Open</button>
    <button id="saveFile">Save</button>
    <br>
    <textarea id="preview"></textarea>
    <script src="index.js"></script>
</body>
</html>

index.js

ここにいろいろ書く。やってることは、

  • OpenDialogで開くファイル名(Path)を取得し、その情報を利用してファイルをオープン。
  • SaveDialogで保存するファイル名(Path)を取得して、その情報を利用してファイルをSave。
index.js
const fs = require('fs');
const { BrowserWindow, dialog } = require('electron').remote;

//html内の要素取得とリスナーの設定
document.querySelector("#openFile").addEventListener('click', () => {
    openFile();
})

document.querySelector("#saveFile").addEventListener('click', () => {
    saveFile();
})

const preview = document.getElementById('preview');

//openFileボタンが押されたとき(ファイル名取得まで)
function openFile() {
    const win = BrowserWindow.getFocusedWindow();
    dialog.showOpenDialog(
        win,
        {
            properties: ['openFile'],
            filters: [
                {
                    name: 'Document',
                    extensions: ['csv', 'txt']
                }
            ]
        },
        (fileNames) => {
            if (fileNames) {
                // alert(fileNames[0]);
                readFile(fileNames[0]); //複数選択の可能性もあるので配列となる。
            }
        }
    )
}

//指定したファイルを読み込む
function readFile(path) {
    fs.readFile(path, (error, data) => {
        if (error != null) {
            alert("file open error.");
            return;
        }
        preview.textContent = data.toString();
    })
}

//saveFileボタンが押されたとき
function saveFile() {
    const win = BrowserWindow.getFocusedWindow();
    dialog.showSaveDialog(
        win,
        {
            properties: ['openFile'],
            filters: [
                {
                    name: 'Documents',
                    extensions: ['csv', 'txt']
                }
            ]
        },
        (fileName) => {
            if (fileName) {
                const data = preview.textContent;
                console.log(data);
                writeFile(fileName, data);
            }
        }
    )
}

//fileを保存(Pathと内容を指定)
function writeFile(path, data) {
    fs.writeFile(path, data, (error) => {
        if (error != null) {
            alert("save error.");
            return;
        }
    })
}

styles.css

まあ、おまけ程度ですが、いちおう。

styles.css
#preview{
    margin-top: 20px;
    width: 300px;
    height: 100px;
}
39
45
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
39
45