はじめに
仕事で使ったときどう使ったかを解説します。
PhpSpreadsheetはPhpExcelの後継で、最近のPHPっぽくなってるらしいです。
https://github.com/PHPOffice/PhpSpreadsheet
今回はxlsx
形式のファイルから情報を読みだして、csv
形式のファイルに書き込みます。
使い方
インストールとrequire
composer require phpoffice/phpspreadsheet
をした後、普通に
require_once "vendor/autoload.php";
で終わりです。
読む
ファイルの読み込み
$reader = new PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$spreadsheet = $reader->load($file_name);
ファイルからシートを取り出す
$sheet = $spreadsheet->getSheetByName("シートの名前");
もしくは、
//選択されているシートを取得
$sheet = $spreadsheet->getActiveSheet();
//2番目のシートを取得。Indexは0スタート
$sheet = $spreadsheet->getSheet(1);
そのシートのセルの情報を取り出す
//B2のセルの値
$sheet->getCell("B2")->getValue();
範囲のセルを配列で取り出す
空のセルにはnull
が入ります
$data = $sheet->rangeToArray("A2:A100");
イテレータで情報を取り出す
イテレータが使えます。上のrangeToArray
は範囲がわかってないと使えませんでしたが、~~これを使うとCtrl+Shift+↓
をしたみたいに空じゃないセルまでを取れます。~~←そんなことはなかった。xlsx
ファイルあるあるのなぜか空のセルまでデータが入っているやつのせいで、null
でもデータ自体は取れてしまう。
- 行ごと。この例だとB1~Bnまで
foreach ($sheet->getRowIterator() as $row) {
var_dump($sheet->getCell("B".$row->getRowIndex())->getValue());
}
- 列ごと。この例だとA1~n1まで
foreach ($sheet->getColumnIterator() as $column) {
var_dump($sheet->getCell($column->getColumnIndex() . "1")->getValue());
}
二つ組み合わせれば範囲を網羅できます。
結合されたセルを取得する
これ!!!これがしたかった!!!!
var_dump($sheet->getMergeCells());
/*
array(
"A1:A10" => string(6)"A1:A10",
"B2:C10" => string(6)"B2:C10"
);
*/
ただの文字列しか取得できませんが、結合の始点と終点を取得することができます!
値そのものは、結合する前のセルに入っています(場所は直接わからない)。
B2
からC10
の範囲にnull
でないセルが1つだけ存在するはずなので、そこの値を取得しましょう。
書く
新しいSpreadSheet
を作る
$spread_sheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
この時点ではファイル形式は指定されません。後に出てくる$writer
がなんのインスタンスかによって最終のファイル形式が決まります。
新しいSheet
を作る
$sheet = $spreadsheet->createSheet(0);
0
を入れないとシートが指定されなくて空白になるっぽい?
既存のSheet
を取得する
$sheet = $spreadsheet->getSheet(0);
最後に保存するとき、csv
じゃなくてxlsx
を指定すると最初から1つシートがあってcreateSheet
すると2枚目ができるので、xlsx
ファイルを作りたいときはこっちのほうが良いっぽい
値をセットしていく
$sheet->setCellValue("A1", "foo");
$sheet->setCellValue("B1", "bar");
$num = 2;
foreach ($data as $key => $value) {
$sheet->setCellValue("A" . $num, $key);
$sheet->setCellValue("B" . $num, $value);
$num++;
}
配列から値をセットする
$array = [
[
"a1",
"b1",
"c1",
null,
"e1"
],
[
"a2",
"b2",
"c2"
]
];
//fromArray(セットする配列, セットしない値, 開始場所のセル)
$sheet->fromArray($array, null, 'A1');
fromArray()
の第二引数はnull
じゃなくても、
$array = [
[
"a1",
"b1",
"c1",
"秘密の値",
"e1"
]
];
$sheet->fromArray($array, "秘密の値", 'A1');
ファイルを保存する
$writer = new PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
$writer->setSheetIndex(0);
$writer->save("hoge.csv");
CSVのときはシートという概念がないので、保存するシートを指定しないと空白になるっぽい
$writer = new PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save("hoge.xlsx");
csv
じゃなくてxlsx
のwriter
を使うとxlsx
形式になる
おわりに
これで基本的な動作は網羅できてる気がします。
メタデータのセットとかセル結合とかもできますが、エクセルを読むことはあっても書くことはないので省略しました。
PHPでExcelを使うのは悪手と言われますが、そんなに難しくないし業務の補助に使う程度なら全然ありだと思います。