Electron에서 File Open 및 Save

Electron에서 파일 조작을 할 필요가 있었기 때문에 Open과 Save의 방법을 메모.

dialog의 제어 방법이 알고 싶은 것이 주목적이므로, 논리는 없음.
csv 로드 표시. 그대로 save한다.

사양



아래와 같은 느낌.
  • open 버튼을 누르면 파이오픈하고 textarea에 표시.
  • save에서 textarea의 내용을 파일로 Save.



  • 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;
    }
    

    좋은 웹페이지 즐겨찾기