【JavaScript】ドラッグ&ドロップでCSVファイルを読み込む
#JavaScript
にメンテナンス済み
ブラウザ上にCSVファイルをドラッグ&ドロップして、中身を2次元配列として扱う方法を紹介します。使うのは標準のAPI(Drag and Drop API と FileReader)だけで、ライブラリは不要です。
全体の流れ
- ドロップ領域に
dragover/dropイベントを登録する dropイベントのevent.dataTransfer.filesからファイルを取得するFileReaderでテキストとして読み込む- 改行・カンマで分割して2次元配列にする
ドラッグ&ドロップのイベントを登録する
まず、ファイルをドロップできる領域を取得し、イベントを登録します。
// ドラッグ&ドロップを許可する領域を取得
const dropArea = document.body;
// 対象領域にファイルがドラッグされている間のイベント
dropArea.addEventListener('dragover', (event) => {
// これを呼ばないと drop イベントが発火しない
event.preventDefault();
// ドラッグしているファイルの表示を「コピー」にする
event.dataTransfer.dropEffect = 'copy';
});
// 対象領域にファイルがドロップされた際のイベント
dropArea.addEventListener('drop', (event) => {
// ドロップされたファイルをブラウザが開いてしまうのを防ぐ
event.preventDefault();
getFiles(event.dataTransfer.files);
});
dragover で preventDefault() を呼ぶのが重要なポイントです。これを忘れると、ドロップしてもブラウザがファイルを開くだけで drop イベントが発火しません。
ドラッグ中に領域のスタイルを変えたい場合は、dragenter / dragleave で CSS クラスを付け外しすると、ユーザーにドロップ可能であることが伝わりやすくなります。
ドロップされた CSV を 2 次元配列に変換する
const getFiles = (files) => {
for (const file of files) {
const reader = new FileReader();
reader.onload = (event) => {
const text = event.target.result;
const csv = text
.split(/\r?\n/)
.filter((row) => row !== '')
.map((row) => row.split(','));
console.log(csv);
};
// テキスト形式で読み込む(文字コードの既定値は UTF-8)
reader.readAsText(file);
}
};
\r?\n で分割しているのは、Windows で作成した CSV の改行コード(CRLF)にも対応するためです。
注意点
ダブルクォートやセル内のカンマには対応していない
上記の split(',') は単純な分割なので、"東京, 渋谷",100 のようにセルの中にカンマや改行を含む CSV は正しく分解できません。実用的なCSVを扱う場合は、Papa Parse などのパーサーライブラリの利用を検討してください。
文字コード
readAsText は既定で UTF-8 として読み込みます。Excel で保存した Shift_JIS の CSV は文字化けするため、第2引数にエンコーディングを指定します。
reader.readAsText(file, 'Shift_JIS');
ファイルの種類を確認する
あらゆるファイルがドロップされ得るため、必要に応じて拡張子を確認しましょう。
if (!file.name.endsWith('.csv')) continue;