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 ダウンロードしたけど、これをネット上で動かすにはどうするの?
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で利用できます。
コメント