Electronでファイル操作する必要があったのでOpenとSaveの方法をメモ。
dialogの制御方法が知りたいのが主目的なので、ロジックはなし。
csvを読み込み表示。そのままsaveする。
仕様
下記のような感じ。
- openボタンを押すとファイオープンし、textareaに表示。
- saveでtextarea内の内容をfileに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;
}