はじめに (対象読者・この記事でわかること)
この記事は、PHPで表計算データを扱うライブラリ「PhpSpreadsheet」を利用し、生成したExcelファイルを読み取り専用に設定して書き出したい開発者向けです。PhpSpreadsheet の基本的な使い方は既に理解しているが、保護機能やパスワード設定で書き出しファイルを編集不可にした方法が分からない方が対象です。本記事を読むことで、シート保護・ブック保護の設定方法や、PhpSpreadsheet の API を用いた読み取り専用ファイルの作成手順を実践的に学べます。
前提知識
この記事を読み進める上で、以下の知識があるとスムーズです。
- PHP の基本的な文法と Composer の利用方法
- PhpSpreadsheet のインストールと簡単な読み書きの経験
PHPSpreadsheetで読み取り専用ファイルを書き出す背景と概要
PhpSpreadsheet は、Excel(.xlsx、.xls)や CSV など様々なフォーマットの読み書きを PHP だけで完結できる強力なライブラリです。しかし、作成したファイルをそのまま配布すると、受取側が自由にセルの内容や数式を編集できてしまいます。業務上、集計結果やレポートを配布するだけで、ユーザーがデータを変更できないようにしたいケースは多く、そこで「読み取り専用」(保護) の設定が必要になります。PhpSpreadsheet ではシート保護やブック保護、さらにはファイル自体にパスワードを設定する機能が提供されており、これらを組み合わせることで、編集不可かつ閲覧は可能なファイルを簡単に生成できます。本章では、保護機能の概念と、実際にどのような設定項目があるかを整理し、目的に応じた保護レベルを選択する指針を示します。
実装手順とポイント
以下では、実際に「読み取り専用」Excel ファイルを作成するまでの手順を順を追って解説します。
ステップ1 環境構築と基本的なファイル生成
Bashcomposer require phpoffice/phpspreadsheet
Php<?php require 'vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; // データ作成 $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->setCellValue('A1', '製品名'); $sheet->setCellValue('B1', '売上'); $sheet->setCellValue('A2', '商品A'); $sheet->setCellValue('B2', 120000); $sheet->setCellValue('A3', '商品B'); $sheet->setCellValue('B3', 85000);
この段階では普通の Excel ファイルを生成できます。次に保護設定を追加します。
ステップ2 シート保護とブック保護の設定
Php// シート保護(パスワード付き) $sheet->getProtection() ->setPassword('sh1tP@ss') ->setSheet(true) // シート全体のロック ->setSort(true) // ソート禁止 ->setInsertRows(true) // 行挿入禁止 ->setFormatCells(true); // 書式変更禁止 // ブック保護(構造の保護) $spreadsheet->getSecurity() ->setLockStructure(true) ->setLockWindows(true) ->setWorkbookPassword('br0kP@ss');
- シート保護:
getProtection()で取得できるオブジェクトに対し、パスワードと許可したい操作を個別に設定します。 - ブック保護:
getSecurity()を使うと、ブック全体の構造(シートの追加・削除・名前変更)やウィンドウ表示のロックが可能です。
ハマった点やエラー解決
-
パスワードが適用されない
- 原因:setPassword()の文字列に全角や余分なスペースが混入していた。
- 対策:trim()とmb_convert_kana()で半角英数字に正規化した上で渡す。 -
保護設定が無視されて Excel が開けない
- 原因:Writerのバージョンが古く、保護情報を書き出せないバグが存在。
- 対策:composer update phpoffice/phpspreadsheetで最新バージョン (>=1.23) にアップデートする。 -
セルのロックが抜けている
- 原因: デフォルトではすべてのセルがロック状態 (protected) ですが、setLocked()で個別に解除し忘れたケース。
- 対策: 必要に応じて$sheet->getStyle('A1:B1')->getProtection()->setLocked(Protection::PROTECTION_UNPROTECTED);を使用。
解決策
上記のエラーは、主に「入力値の正規化」と「ライブラリのバージョン管理」で回避できます。特にパスワードは半角英数字のみを使用し、余計な空白や全角文字が混入しないように前処理を入れるのが安全です。また、保護機能を利用する場合は、必ず Writer が対応しているバージョンであることを composer show で確認してください。
完成コード(まとめ)
Php<?php require 'vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Style\Protection; $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->setCellValue('A1', '製品名') ->setCellValue('B1', '売上') ->setCellValue('A2', '商品A') ->setCellValue('B2', 120000) ->setCellValue('A3', '商品B') ->setCellValue('B3', 85000); // ---- シート保護設定 ---- $sheet->getProtection() ->setPassword('sh1tP@ss') ->setSheet(true) ->setSort(true) ->setInsertRows(true) ->setFormatCells(true); // ---- ブック保護設定 ---- $spreadsheet->getSecurity() ->setLockStructure(true) ->setLockWindows(true) ->setWorkbookPassword('br0kP@ss'); // ---- 書き出し ---- $writer = new Xlsx($spreadsheet); $writer->save('readonly_report.xlsx');
このスクリプトを実行すると、readonly_report.xlsx が生成され、シートとブックの両方がパスワードで保護された状態になります。Excel で開くと「編集が制限されています」というメッセージが表示され、パスワード入力なしではセルの内容を変更できません。
まとめ
本記事では、PhpSpreadsheet を用いてシート保護・ブック保護およびパスワード設定を組み合わせ、読み取り専用の Excel ファイルを安全に書き出す具体的な手順を解説しました。
- シート保護でセル単位の編集をロック
- ブック保護でシート構成の変更を防止
- パスワードを設定して不正な解除を防ぐ
これらを適切に組み合わせることで、配布用レポートや集計結果を安全に共有できます。今後は、PDF 変換やクラウドストレージへの自動アップロードといった、保護ファイルを使ったワークフロー自動化についても取り上げる予定です。
参考資料
- PhpSpreadsheet 公式ドキュメント – Protection
- PhpSpreadsheet 公式リポジトリ (GitHub)
- 「Excel VBA と PHPSpreadsheet によるファイル保護」(技術書籍、2023年出版)
