HOWTO · React
React で CSV ファイルをアップロードして読み取る
この記事では React で CSV ファイルを読み込む方法を紹介します。
このページの内容
Reactアプリで選択したCSVファイルを読み取るには、ファイル入力を使い、onChangeハンドラーでそのFileオブジェクトを読み込みます。ブラウザーのFileReader APIが読み取るのはファイルのテキストであり、CSVテキストを行や列に変換するわけではありません。CSVの構造を解析して行データを取得するには、papaparseを使います。
ReactでFileReaderを使ってCSVファイルを読み取る
.csvファイルを受け付けるネイティブのファイル入力を追加し、選択されたファイルをFileReader.readAsText()に渡します。読み込みは非同期で行われるため、onloadで結果を処理します。次のブラウザー用ページのソース例は未実行で、ファイルのテキストを表示します。表示されるファイル入力のラベルは英語のままです。Reactコンポーネントでは、同じ入力をJSXに記述し、textContentを直接設定する代わりに、onloadハンドラーからコンポーネントの状態を更新します。
次のNode.jsの例では、単純なCSVテキストを行オブジェクトに変換する方法を示します。この例は、フィールドが引用符で囲まれておらず、各行の列数が同じであることを前提としています。一般的なCSV構文を含むファイルには、CSVパーサーを使ってください。
const csv = "name,score\nAva,18\nNoah,21";
const [headerLine, ...dataLines] = csv.trim().split(/\r?\n/);
const headers = headerLine.split(",");
const rows = dataLines.map((line) => {
const values = line.split(",");
return Object.fromEntries(headers.map((header, index) => [header, values[index]]));
});
console.log(JSON.stringify(rows, null, 2));
[
{
"name": "Ava",
"score": "18"
},
{
"name": "Noah",
"score": "21"
}
]
<label for="csv-file">Choose a CSV file</label>
<input id="csv-file" type="file" accept=".csv,text/csv">
<pre id="csv-text"></pre>
<script>
const input = document.querySelector("#csv-file");
const output = document.querySelector("#csv-text");
input.addEventListener("change", (event) => {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = () => {
output.textContent = String(reader.result);
};
reader.onerror = () => {
output.textContent = "The file could not be read.";
};
reader.readAsText(file);
});
</script>
Reactでは、同等の入力ハンドラーでreader.onload内からsetCsvText(String(reader.result))を呼び出し、その状態を<pre>に表示できます。この例が読み取るのは、選択されたファイルのテキストだけです。行、ヘッダー、引用符で囲まれた値、区切り文字をCSVデータとして解釈するには、ファイルのテキストをCSVパーサーに渡すか、解析ライブラリを直接使います。
Reactでpapaparseライブラリを使ってCSVファイルを読み取る
Reactプロジェクトのディレクトリでnpm install papaparseを実行してPapa Parseをインストールし、import Papa from "papaparse"で読み込みます。ネイティブのファイル入力を使い、選択されたFileをPapa.parseに渡します。completeコールバックには解析結果が渡され、そのdataプロパティに解析済みの行が含まれます。コンポーネントの状態を使って行を表示し、解析結果のフィードバックを示すにはerrorsを確認します。このブラウザー用ページのソース例は未実行で、Papa Parseがグローバル変数Papaとして利用できることを前提としています。Reactコンポーネントでは、上記のモジュールインポートを使い、コールバックの処理をonChangeに記述します。この例が示すのはDOMへの出力であり、Reactによるレンダリングではありません。
<label for="csv-file">Choose a CSV file</label>
<input id="csv-file" type="file" accept=".csv,text/csv">
<pre id="csv-rows"></pre>
<script>
const input = document.querySelector("#csv-file");
const output = document.querySelector("#csv-rows");
input.addEventListener("change", (event) => {
const file = event.target.files[0];
if (!file) return;
Papa.parse(file, {
header: true,
complete: (results) => {
output.textContent = JSON.stringify(results.data, null, 2);
if (results.errors.length > 0) {
console.warn("CSV parsing reported issues:", results.errors);
}
},
error: (error) => {
output.textContent = `The file could not be parsed: ${error.message}`;
}
});
});
</script>
header: trueを指定すると、Papa Parseは最初の行をオブジェクトのキーとして使います。そのため、results.dataの各要素は列名をキーに持つデータ行になります。Reactコンポーネントでは、complete内でsetRows(results.data)を呼び出し、状態に保存した行を表示できます。解析時の警告をユーザーに知らせる必要がある場合は、results.errorsを画面に表示します。生のテキストが必要で、形式を自分で処理する場合はFileReaderが便利です。CSVの内容を構造化された行に変換する場合は、Papa Parseを使えます。