フォルダの中身をCSVに変換するブラウザツールを作った – Folder To CSV

はじめに

最近、個人的に「フォルダの中身をCSVファイルにexportしたいな〜」と考えることがあった。

例えば、プロジェクトのファイル構成を一覧にしたり、写真フォルダのファイル情報をまとめたり、そういった用途だ。エクスプローラーで画面をスクロールしながら手動でメモみたいな作業は面倒すぎる。

そこで「ブラウザだけで完結するツールがあれば便利じゃない?」と思い作成したのが Folder To CSV です。

コマンドで dir /b > filelist.csv したり、専用のフリーソフト入れたりというのは一旦置いておく

公開URL:https://inoue-web.work/creative/folder-to-csv/

Folder To CSVとは?

一言で言うと、フォルダ内のファイル情報を一覧化し、CSVやJSONなど複数形式でエクスポートできるブラウザ専用ツール

一番の特徴は バックエンドが不要 なこと。ファイルはすべてローカル(ブラウザ内)で処理され、外部サーバーに送信されることはない。プライバシー面でも安心。

主な機能

  • フォルダの再帰的スキャン:サブフォルダの中身もすべて取得
  • 出力カラムの自由選択:ファイル名、拡張子、サイズ、更新日時、親ディレクトリ、相対パス、MIMEタイプから必要なものだけ選べる
  • 6種類のエクスポート形式:CSV、JSON、Markdown、HTML、TSV、XML
  • リアルタイムフィルタリング:ファイル名で即座に絞り込み
  • ソート機能:各カラムで昇順/降順に並べ替え可能
  • ページネーション:100件ごとにページ分け
  • キーボードショートカットCtrl + E でワンクリックエクスポート

使い方

動作環境

  • モダンブラウザ(Chrome 86+ / Edge 86+ 推奨)
  • File System Access API が利用可能な事

ブラウザで https://inoue-web.work/creative/folder-to-csv にアクセスし、「フォルダを選択」ボタンから対象フォルダを選ぶだけ。

基本的な流れ

  1. ページを開く
  2. 「フォルダを選択」をクリック
  3. 出力したいカラムにチェックを入れる
  4. エクスポート形式を選ぶ
  5. 「エクスポート」をクリック → ダウンロードされる

技術的なポイント

ここからは、作った側の視点で技術的な話をする。個人的に色々試行錯誤したので、興味がある人向けに書いていく。

ファイル読み取り:File System Access API

一番の技術的なポイントは、フォルダの読み取り方法。

最近のモダンブラウザ(Chrome系)では File System Access API が使える。これを使うと showDirectoryPicker() でフォルダ選択ダイアログを表示し、ユーザーが選んだフォルダの中身を再帰的に読み取ることができる。

// File System Access APIを使ったフォルダ読み取り
async function readWithFileSystemAccess() {
  const dirHandle = await window.showDirectoryPicker({ mode: 'read' });
  state.folderName = dirHandle.name;
  return traverseDirectory(dirHandle, '');
}

// 再帰的にディレクトリを探索
async function traverseDirectory(dirHandle, path) {
  const results = [];
  for await (const entry of dirHandle.values()) {
    if (entry.kind === 'directory') {
      // サブフォルダだったら再帰呼び出し
      const sub = await traverseDirectory(entry, path ? path + '/' + entry.name : entry.name);
      results.push(...sub);
    } else {
      // ファイルだったら情報を取得
      const file = await entry.getFile();
      results.push({
        name: file.name,
        size: file.size,
        lastModified: file.lastModified,
        // ... 他のプロパティ
      });
    }
  }
  return results;
}

ただ、このAPIはまだすべてのブラウザで対応しているわけではない。そこで レガシーブラウザ対応 も導入した。showDirectoryPicker が使えない環境では、自動的に webkitdirectory 属性付きの <input type="file"> にフォールバックする。

// ブラウザ判定とフォールバック
if ('showDirectoryPicker' in window && window.isSecureContext !== false) {
  // File System Access APIが使える環境
  files = await readWithFileSystemAccess();
} else {
  // レガシーモード: webkitdirectoryにフォールバック
  folderInput.click();
}

エクスポート処理の設計

6種類の出力形式に対応するため、各フォーマットの生成ロジックを exporters オブジェクトにまとめた。

const exporters = {
  csv(data, cols) {
    const header = cols.map(c => c.label).join(',');
    const rows = data.map(f => cols.map(c => escCsv(getColumnValue(f, c.key))).join(','));
    // UTF-8 BOM付き(Excel対応)
    return { content: '\uFEFF' + header + '\n' + rows.join('\n'), mime: 'text/csv;charset=utf-8', ext: 'csv' };
  },
  json(data, cols) {
    const arr = data.map(f => {
      const o = {};
      cols.forEach(c => { o[c.label] = getColumnValue(f, c.key); });
      return o;
    });
    return { content: JSON.stringify(arr, null, 2), mime: 'application/json;charset=utf-8', ext: 'json' };
  },
  markdown(data, cols) {
    const header = '| ' + cols.map(c => c.label).join(' | ') + ' |';
    const sep = '| ' + cols.map(() => '---').join(' | ') + ' |';
    const rows = data.map(f => '| ' + cols.map(c => String(getColumnValue(f, c.key)).replace(/\|/g, '\\|')).join(' | ') + ' |');
    return { content: header + '\n' + sep + '\n' + rows.join('\n'), mime: 'text/markdown;charset=utf-8', ext: 'md' };
  },
  // ... html, tsv, xml も同様の構造
};

CSVの場合は UTF-8 BOM を先頭に付与することで、Excelで開いたときに文字化けを防いでいる。こういう小細工が意外と重要。

UIデザイン:ガラスモーフィズム

見た目は何か流行ってる気がする ガラスモーフィズム を採用。背景にオーブ(光る球体)とグリッドパターンを配置し、カード要素には半透明のぼかし効果をつけた。

CSS Custom Propertiesを使ってカラーパレットを管理している。

:root {
  --bg-dark: #0a0a1a;
  --bg-card: rgba(255, 255, 255, 0.03);
  --border: rgba(255, 255, 255, 0.08);
  --cyan: #00f0ff;
  --pink: #ff00aa;
  --yellow: #ffcc00;
}

ファイルアイコンも拡張子ごとに色分けされるようになっていて、コードファイルならシアン、画像ならグリーン、アーカイブならオレンジ、という風に視覚的に区別しやすくした。

パフォーマンス考慮

大量のファイルを扱うこともあるので、いくつかパフォーマンス対策を施している。

  • ページネーション:100件ごとにページ分けし、一度に描画するDOM要素を制限
  • フィルタのデバウンス:入力250ms後にフィルタを実行し、キー入力ごとの再描画を防止
  • row-enter アニメーション:表示行数に応じて animation-delay を分散し、一括DOM書き換え時のラグを軽減

技術スタックまとめ

項目技術
フレームワークなし(Vanilla JavaScript)
ファイル読み取りFile System Access API / webkitdirectory
スタイリングCSS Custom Properties + ガラスモーフィズム
フォントGoogle Fonts(Orbitron / Noto Sans JP / JetBrains Mono)
バックエンドなし

フレームワークを使わずに書いた理由は、ツールとして軽量に保ちたかったから。ReactやVueを入れるほどコンポーネント分割する必要もないし、最終的に1つのHTML+CSS+JSに収まるのが個人的には好きだ。

まとめ

Folder To CSV は、日常的に「フォルダの中身を一覧にしたい」というニーズを満たすためのシンプルなツール。

  • サーバー不要
  • ファイルはローカルで完結
  • CSV、JSON、Markdownなど6形式に対応

個人開発のプロダクトとして、少しでも役に立てれば嬉しい。

https://inoue-web.work/creative/folder-to-csv