CSVテーブルに検索フォームとページネーションを付ける方法【PHP/CSV/HTML/CSS・サンプルコード付き】

テーブル
無料ツール
テーブルを自由に作成

行数・列数・枠線・背景色・文字色・セル結合などを設定して、HTMLとCSSを自動生成できます。

テーブル作成ツールを使う
新しいタブで開きます

CSVテーブルに検索フォームとページネーションを付ける方法

CSVファイルに保存したデータをテーブルで表示すると、データ件数が増えるほど目的の情報を探しにくくなります。そこで今回は、CSVから読み込んだ社員一覧に検索フォームとページネーションを組み合わせ、必要なデータを探しやすくする方法を紹介します。

サンプルでは100件の社員データをCSVファイルから読み込み、社員番号・氏名・部署・役職・出身地をテーブルに表示します。通常は1ページにつき10件ずつ表示し、ページ番号を使って一覧を切り替えられるようにします。さらに検索フォームへキーワードを入力すると、CSVデータから条件に一致する社員を絞り込み、検索結果に合わせてページネーションも切り替わる構成にします。

商品一覧や会員一覧、社員名簿など、CSVで管理している多くのデータをWebページ上で見やすく表示したい場合に利用できます。PHPでCSVの読み込み・検索・ページ分割を行うため、JavaScriptに頼らず、検索条件とページ番号を使って一覧を表示できるサンプルです。

コードについて 本記事のコードはサンプルコードです。ご利用前に必ず動作確認を行ってください。
免責事項 本コードの利用により発生した損害について、当サイトは一切の責任を負いません。

デモ

社員一覧

100件中 1〜10件を表示

社員番号 氏名 部署 役職 出身地

検索フォームに社員番号・氏名・部署・役職・出身地を入力して「検索」をクリックしてください。検索結果が10件を超える場合は、ページ番号をクリックして続きを確認できます。

コードをコピーして使おう!

<?php

// 読み込むCSVファイル
$csv_file = 'data.csv';

// 1ページに表示する件数
// 10を変更すると、1ページに表示する社員数が変わります。
$per_page = 10;

// 検索キーワードを取得
// 検索されていない場合は空文字にします。
$keyword = isset($_GET['keyword'])
    ? trim($_GET['keyword'])
    : '';

// 現在のページ番号を取得
// pageが指定されていない場合は1ページ目を表示します。
$page = isset($_GET['page'])
    ? (int)$_GET['page']
    : 1;

// 1未満のページ番号が指定された場合は1へ戻します。
if ($page < 1) {
    $page = 1;
}

// CSVから読み込んだ社員データを保存する配列
$rows = [];

// CSVファイルを読み込み専用で開きます。
if (($handle = fopen($csv_file, 'r')) !== false) {

    // 1行目の見出し行を読み飛ばします。
    fgetcsv($handle);

    // CSVを1行ずつ読み込みます。
    while (($data = fgetcsv($handle)) !== false) {

        // 検索キーワードが入力されている場合
        if ($keyword !== '') {

            // 社員番号・氏名・部署・役職・出身地を
            // 1つの文字列にまとめて検索します。
            $search_text = implode(' ', $data);

            // キーワードが含まれていない行は一覧へ追加しません。
            if (mb_stripos($search_text, $keyword) === false) {
                continue;
            }
        }

        // 検索条件に一致したデータを保存します。
        $rows[] = $data;
    }

    // CSVファイルを閉じます。
    fclose($handle);
}

// 検索後のデータ件数
$total_items = count($rows);

// 検索結果から総ページ数を計算します。
// 10件表示の場合、25件なら3ページになります。
$total_pages = max(
    1,
    (int)ceil($total_items / $per_page)
);

// 総ページ数を超えるページが指定された場合は
// 最後のページへ移動します。
if ($page > $total_pages) {
    $page = $total_pages;
}

// 現在ページで読み始める位置
$offset = ($page - 1) * $per_page;

// 現在ページに表示するデータだけを取り出します。
$page_rows = array_slice(
    $rows,
    $offset,
    $per_page
);

// 件数表示の開始番号
$first_number = $total_items === 0
    ? 0
    : $offset + 1;

// 件数表示の終了番号
$last_number = min(
    $offset + $per_page,
    $total_items
);

?>
<!DOCTYPE html>
<html lang="ja">
<head>

  <!-- 文字コード -->
  <meta charset="UTF-8">

  <!-- スマートフォン対応 -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <!-- ページタイトル -->
  <title>CSVテーブルに検索フォームとページネーションを付ける</title>

  <!-- CSSファイル -->
  <link rel="stylesheet" href="style.css">

</head>
<body>

  <!-- 社員一覧全体 -->
  <div class="csv-pagination-search_wrap">

    <!-- タイトル -->
    <div class="csv-pagination-search_title">
      社員一覧
    </div>

    <!-- 検索フォーム -->
    <form
      class="csv-pagination-search_form"
      method="get"
      action=""
    >

      <!--
        社員番号・氏名・部署・役職・出身地を検索する入力欄
        検索後も入力したキーワードをvalueへ表示します。
      -->
      <input
        class="csv-pagination-search_input"
        type="search"
        name="keyword"
        value="<?= htmlspecialchars($keyword, ENT_QUOTES, 'UTF-8') ?>"
        placeholder="社員番号・氏名・部署・役職・出身地で検索"
      >

      <!-- 検索ボタン -->
      <button
        class="csv-pagination-search_button"
        type="submit"
      >
        検索
      </button>

    </form>

    <!-- 検索結果と現在表示している件数 -->
    <p class="csv-pagination-search_count">
      <?= $total_items ?>件中
      <?= $first_number ?>〜<?= $last_number ?>件を表示
    </p>

    <!-- 横幅が狭い画面では、この部分だけ横スクロールします。 -->
    <div class="csv-pagination-search_table-wrap">

      <!-- 社員一覧テーブル -->
      <table class="csv-pagination-search_table">

        <!-- テーブル見出し -->
        <thead>
          <tr>
            <th>社員番号</th>
            <th>氏名</th>
            <th>部署</th>
            <th>役職</th>
            <th>出身地</th>
          </tr>
        </thead>

        <!-- CSVから読み込んだ社員データ -->
        <tbody>

          <?php if (count($page_rows) > 0): ?>

            <?php foreach ($page_rows as $row): ?>

              <tr>
                <td><?= htmlspecialchars($row[0], ENT_QUOTES, 'UTF-8') ?></td>
                <td><?= htmlspecialchars($row[1], ENT_QUOTES, 'UTF-8') ?></td>
                <td><?= htmlspecialchars($row[2], ENT_QUOTES, 'UTF-8') ?></td>
                <td><?= htmlspecialchars($row[3], ENT_QUOTES, 'UTF-8') ?></td>
                <td><?= htmlspecialchars($row[4], ENT_QUOTES, 'UTF-8') ?></td>
              </tr>

            <?php endforeach; ?>

          <?php else: ?>

            <!-- 検索結果が0件の場合 -->
            <tr>
              <td
                class="csv-pagination-search_empty"
                colspan="5"
              >
                該当するデータがありません
              </td>
            </tr>

          <?php endif; ?>

        </tbody>

      </table>

    </div>

    <?php if ($total_items > 0 && $total_pages > 1): ?>

      <!-- ページネーション -->
      <nav
        class="csv-pagination-search_nav"
        aria-label="ページネーション"
      >

        <?php for ($i = 1; $i <= $total_pages; $i++): ?>

          <!--
            検索中にページを移動しても検索条件を維持するため、
            keywordをURLへ引き継ぎます。
          -->
          <a
            class="csv-pagination-search_page<?= $i === $page ? ' csv-pagination-search_active' : '' ?>"
            href="?keyword=<?= urlencode($keyword) ?>&page=<?= $i ?>"
            <?= $i === $page ? 'aria-current="page"' : '' ?>
          >
            <?= $i ?>
          </a>

        <?php endfor; ?>

      </nav>

    <?php endif; ?>

  </div>

</body>
</html>
コードをコピーする場合 使用するコードのタブを選び、「このタブをコピー」をクリックすると、現在表示中のコードをコピーできます。
サンプル一式を取得する場合 HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
Q ダウンロードしたけど、これをネット上で動かすにはどうするの?
A

Googleアカウントがあれば、InfinityFreeで無料サーバーを作成して、ダウンロードしたサンプルをネット上で動かせます。

InfinityFreeを初めて利用する場合は①から、すでにサーバーを作成している場合は②へ進んでください。

ファイル構成と設置方法

このサンプルはPHP、CSS、CSVの3ファイルで構成されています。data.csvには100件の社員データを保存し、index.phpでCSVを読み込んで検索とページ分割を行います。通常は1ページに10件ずつ表示され、検索フォームへ社員番号・氏名・部署・役職・出身地を入力すると、一致したデータだけをテーブルへ表示します。検索結果が複数ページになる場合は、その検索条件を維持したままページ番号から続きを表示できます。

sample/
    ├── index.php
    ├── style.css
    └── data.csv

各ファイルの役割
index.phpはdata.csvを読み込み、検索キーワードによる絞り込み、表示件数の計算、ページ分割、テーブルとページネーションの出力を行うファイルです。$per_page = 10;を変更すると、1ページに表示する件数を変更できます。

style.cssは検索フォーム、検索ボタン、件数表示、社員一覧テーブル、ページネーションのデザインを設定するファイルです。横幅、余白、文字サイズ、枠線、角丸、背景色などを変更できます。

data.csvは社員データを保存するCSVファイルです。1行目を「社員番号,氏名,部署,役職,出身地」の見出しとし、2行目以降へ社員データを追加します。

設置方法・使い方
sampleフォルダへindex.php、style.css、data.csvを配置し、sampleフォルダごとPHPが動作するサーバーへアップロードしてください。ブラウザからsample/index.phpへアクセスすると社員一覧が表示されます。検索フォームへ社員番号、氏名、部署、役職、出身地のいずれかを入力して「検索」を押すと、一致したCSVデータだけが表示されます。検索結果が10件を超えた場合はページ番号が表示され、ページを移動しても検索キーワードが維持されます。PHPを動かす無料サーバーを準備する場合は、InfinityFreeで無料サーバーを作る方法を参考にしてください。sampleフォルダ内のファイルをサーバーへアップロードする方法は、InfinityFreeのFile Managerの使い方で確認できます。

カスタマイズできる内容
data.csvを編集すると、テーブルへ表示する社員データを変更できます。今回のコードでは1列目から順番に社員番号、氏名、部署、役職、出身地として扱います。index.phpでは1ページに表示する件数を変更できます。style.cssでは検索フォームの入力欄や検索ボタン、テーブル、ページ番号の横幅、高さ、余白、枠線、角丸、背景色、文字色などを変更できます。

数値調整
index.php
$per_page = 10;
1ページに表示する社員データの件数です。10を大きくすると1ページに表示される件数が増えてページ数が少なくなり、小さくすると1ページの件数が減ってページ数が多くなります。

style.css
padding:40px 20px;
ページ全体の上下・左右の余白です。40pxは上下、20pxは左右の余白で、値を大きくすると画面端との間隔が広がります。

padding:24px;
社員一覧全体の内側余白です。値を大きくすると内容と外側との間隔が広がります。

gap:10px;
検索入力欄と検索ボタンの間隔です。値を大きくすると2つの間隔が広がります。

min-width:220px;
検索入力欄の最小横幅です。値を大きくすると入力欄が広くなります。

height:44px;
検索入力欄と検索ボタンの高さです。値を大きくすると高さが増します。

border-radius:10px;
検索入力欄、検索ボタン、ページ番号の角丸です。値を大きくすると丸みが強くなり、0にすると四角になります。

min-width:760px;
社員一覧テーブルの最小横幅です。値を大きくするとテーブル全体を広く確保できます。

border-radius:18px;
テーブルを囲む部分の角丸です。値を大きくすると丸みが強くなり、0にすると四角になります。

padding:14px 16px;
テーブルセルの内側余白です。14pxは上下、16pxは左右の余白で、値を大きくするとセル内の間隔が広がります。

gap:8px;
ページ番号同士の間隔です。値を大きくすると各ページ番号の間隔が広がります。

min-width:42px;・height:42px;
ページ番号の最小横幅と高さです。値を大きくするとページ番号のボタンが大きく表示されます。

レスポンシブ対応
このサンプルはレスポンシブ対応です。style.cssのwidth:100%によって社員一覧全体が画面幅に合わせて縮小され、検索フォームはflex-wrap:wrap;によって横幅が足りない場合に折り返されます。社員一覧テーブルはmin-width:760px;を維持しながら、外側のoverflow-x:auto;によって狭い画面ではテーブル部分だけを横スクロールできます。ページネーションも折り返しに対応しているため、スマートフォン・タブレット・PCで利用できます。


こちらもおすすめ


コメント