2018年4月12日木曜日

PHPExcel の removeColumnByIndex で、結合された列を削除した場合の挙動について


オフィス狛 技術部 Maruruです。

今となっては非推奨となった PHPExcel ですが、昔からのシステムであれば、多く使用されています。
そんなシステムで、テンプレートExcelファイルを読み込み、そこに値を書き出し、出力するという、よくあるシステムを構築していたのですが、
そこで列を削除する removeColumnByIndex の挙動が想定していたものと異なってしまったので、その件についてまとめてみました。

【前提】使用するテンプレートファイルとソースコード

上記が、テンプレートファイルです。
上から2行は表の見出しとする為、セル結合しています。
対象の月に合わせて末日を変更するため、 removeColumnByIndex を使用して列を削除することを想定しています。
// $daysには月の合計日数が入っています。
if ($days < 31) {
    foreach (range(0,30-$days) as $column) {
        $sheet->removeColumnByIndex( 30 - $column );
    }
}

・末日が31日ではない月を対象に処理を実行

1)末日が28日の場合

28の隣に削除したはずの列が残ったままになってしまいます。
その影響で見出しで使用する2行も1列分幅が広くなってしまいます。

2)末日が30日の場合

こちらも同様に30の隣に削除したはずの列が残ったままになってしまいます。
その影響で見出しで使用する2行も1列分幅が広くなってしまいます。

・末日が31日の月を対象に処理を実行


こちらはそもそも列削除処理が呼ばれないので、想定通りの結果となりました。

・セル結合していた箇所を解除

次にテンプレートファイルの上2行、見出し部分のセル結合を解除してから実行してみました。

1)末日が28日の場合

2)末日が30日の場合

どちらの場合も末日のあとに1列余分に残ってしまいました。
セルが「結合されている、されていない」は関係無く、何列削除しようと、最後の1列だけ削除されない(値は消えているけど)みたいですね。

今回はテンプレートファイルの見出しとして使用する上2行と日付のテーブルの横幅を合わせるだけで問題なかったので、
最後の列は無視して、上2行の見出し部分を unmergeCells したあとに mergeCells して横幅を合わせました。


0 件のコメント:

コメントを投稿