116
128

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PhpSpreadsheetの使い方

Last updated at Posted at 2018-07-23

はじめに

仕事で使ったときどう使ったかを解説します。
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');

とすると、以下の画像のように値が入る。
image.png

fromArray()の第二引数はnullじゃなくても、

$array = [
    [
        "a1",
        "b1",
        "c1",
        "秘密の値",
        "e1"
    ]
];

$sheet->fromArray($array, "秘密の値", 'A1');

みたいにすると以下の画像のように秘密の値がセットされない。
image.png

ファイルを保存する

$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じゃなくてxlsxwriterを使うとxlsx形式になる

おわりに

これで基本的な動作は網羅できてる気がします。
メタデータのセットとかセル結合とかもできますが、エクセルを読むことはあっても書くことはないので省略しました。
PHPでExcelを使うのは悪手と言われますが、そんなに難しくないし業務の補助に使う程度なら全然ありだと思います。

116
128
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
116
128

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?