HTML+JavaScriptでBasicなファイルのエクスポートとインポート
HTMLとJavaScriptを用いてファイルのエクスポート・インポートを実装する際のBasicな記述です。
以下を想定してみます。
- ファイル形式:json
- エクスポート:ファイルとしてローカルに保存するまで
- インポート:ローカルに保存された単一ファイルを読み込み、JavaScript内部で読み取れる状態になるまで
- 動作確認ブラウザ:
- Google Chrome
- Microsoft Edge (Chromium)
- Mozilla Firefox
- Safari (macOS)
- Safari (iOS)
- Safari (iPadOS)
エクスポート処理
まずはボタンを用意します。
<button id="export" aria-label="export">エクスポート</button>
基本的な処理が以下です。
/** * export処理 */const exportData = () => { // 適当なデータ const data = { name: 'Taro', age: 28 }
const json = JSON.stringify(data, null, ' ') const blob = new Blob([json], { type: 'application/json' }) const url = URL.createObjectURL(blob)
const linkTag = document.createElement('a') linkTag.href = url linkTag.download = 'export-data.json' linkTag.click()
URL.revokeObjectURL(url) linkTag.remove()}
const btn = document.querySelector('#export')btn.addEventListener('click', exportData, false)
ポイントは以下になります。
data
をJSON.stringify
で文字列に変換JSON.stringify
の第三引数はインデントを指定できます(エクスポートしたファイルはエディターなどで編集される可能性を考えてスペース1つ分のインデントを指定)new Blob()
でBlobオブジェクトを生成URL.createObjectURL
でBlobオブジェクトのURLを生成- 生成した
a
ノードにオブジェクトのURLをセットしダウンロード URL.revokeObjectURL
で、URL.createObjectURL
で生成したURLを解放- 最後に生成した
a
ノードを削除
インポート処理
まずは<input type="file">
タグを用い、ファイルの選択手段を用意します。
<label id="import" for="file-upload" aria-label="import"> <span>インポート</span> <input id="file-upload" type="file" style="display: none;"></label>
基本的な処理が以下です。
/** * import処理 * @param {object} e */const importData = e => { const result = JSON.parse(e.target.result)
// 別途バリデーション用意し通す const valid = validate(result)
if(!valid) { return false }
console.log(result)}
// readerを用意しonloadイベントにimportData指定const reader = new FileReader()reader.onload = importData
const fileSelector = document.querySelector('#import')const fileUploadInput = document.querySelector('#file-upload')
fileSelector.addEventListener('change', e => { const file = e.target.files[0] fileUploadInput.value = '' // 同名ファイルの読み込み時にイベント発火が出来ないのでクリア
if (!file) { return false }
if (file.type !== 'application/json') { return false }
reader.readAsText(file)}, false)
ポイントは以下になります。
new FileReader()
でFileReaderを生成reader
のonloadにインポートを行う処理(上記だとimportData
)を指定- ファイル選択時、同名ファイルの読み込み時にイベント発火が出来なくなるのを防ぐため
fileUploadInput.value = ''
でクリア reader.readAsText()
でFile
の内容を文字列として格納- 格納した文字列を
JSON.parse
でパース - 必要に応じてバリデーション等を行う