はじめに
月別切り替え・円グラフ・予算設定・固定費自動追加に続き、今回はCSVエクスポート機能を実装しました。
【シンプル家計簿】https://kakeibo-khaki.vercel.app/
ブラウザに保存されたデータをCSVファイルとしてダウンロードできます。Excelでも文字化けしないように工夫しています。
追加した機能
- 月ナビの横に「📥 CSV」ボタンを配置
- ボタンを押すとモーダルが開き「今月のデータ」か「全データ」を選択できる
- Excelで文字化けしないBOM付きUTF-8で出力
- データが0件の場合はアラートを表示
実装の概要
1. CSVエクスポート関数
function exportCSV(type){
// エクスポート対象を決定
const target = type === 'month' ? getMonthItems() : items;
const filename = type === 'month'
? `家計簿_${currentYear}年${currentMonth}月.csv`
: `家計簿_全データ.csv`;
if(target.length === 0){
alert('エクスポートするデータがありません。');
closeModal();
return;
}
// ヘッダー行
const headers = ['日付', 'メモ', 'カテゴリ', '種別', '金額', '固定費'];
// データ行を作成
const rows = target.map(i => [
i.date,
i.memo,
i.cat,
i.type === 'income' ? '収入' : '支出',
i.amount,
i.isFixed ? '〇' : ''
]);
// ヘッダー+データを結合してCSV文字列を生成
const csv = [headers, ...rows]
.map(row => row.map(cell => `"${String(cell).replace(/"/g, '""')}"`).join(','))
.join('\n');
// BOM付きUTF-8でダウンロード
const blob = new Blob(['\uFEFF' + csv], { type: 'text/csv;charset=utf-8' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
closeModal();
}
2. ポイント解説
① スプレッド構文でヘッダーとデータを結合
const csv = [headers, ...rows]
.map(row => ...)
.join('\n');
[headers, ...rows]は「headersを先頭に、rowsの要素を展開して1つの配列にする」という意味です。
// イメージ
['日付','メモ',...], // headers
['2026-05-01','スーパー',...], // rows[0]
['2026-05-03','電気代',...], // rows[1]
② ダブルクォートのエスケープ
cell => `"${String(cell).replace(/"/g, '""')}"`
CSVでは各セルをダブルクォートで囲みます。セルの中にダブルクォートがある場合は""に置換してエスケープします。
③ BOM付きUTF-8でExcelの文字化けを防ぐ
const blob = new Blob(['\uFEFF' + csv], { type: 'text/csv;charset=utf-8' });
\uFEFFはBOM(Byte Order Mark)と呼ばれる文字コードの識別子です。これを先頭に付けることでExcelが「UTF-8で書かれたファイル」と認識し、日本語が文字化けしなくなります。
④ ダウンロード後にURLを解放
URL.revokeObjectURL(url);
createObjectURL()で作成したURLはメモリを使い続けるため、ダウンロード後にrevokeObjectURL()で解放しています。
3. モーダルの開閉
function openModal(){ document.getElementById('csv-modal').classList.add('open'); }
function closeModal(){ document.getElementById('csv-modal').classList.remove('open'); }
.modal-overlay{ display: none; }
.modal-overlay.open{ display: flex; }
予算パネルと同様にclassListでクラスを付け外しするだけで開閉しています。
まとめ
| 変更箇所 | 内容 |
|---|---|
| CSS | CSVボタン・モーダルのスタイルを追加 |
| HTML | モーダルのHTMLを追加・月ナビにCSVボタンを追加 |
| JS関数 |
openModal() closeModal() exportCSV()を追加 |
次回はカテゴリ追加・編集機能の実装を予定しています。
★開発したアプリ
【シンプル家計簿】https://kakeibo-khaki.vercel.app/