自分が作ったわけではない、以下のコードがあります。
・処理をキックすると、DB(というか外部サービス(ぶっちゃけkintone))からデータを取り込む
・取り込んだデータを、4種のエクセル帳票に書き出す
・エクセル帳票をpdf化及び結合してダウンロードする

今回は、上記処理に対し
「ページ採番(「現在ページ/総ページ数」の印字) がしたい」
という要求があり、 これがなかなか難しかった。というお話。

言語はPHPで、PHPExcelのライブラリを使っています。
帳票のエクセルの拡張子は「.xls」です。
帳票テンプレートとしては、総合計用の帳票が1種、明細用の帳票が2種あります。
3種の異なるテンプレートから、4種の帳票を出力します。
(1種テンプレートの使いまわしがあるということです)

さて、ページ採番なので、エクセルのフッタに出力すればいいかなと思いました。
以下のページを参考にしました。
ヘッダー、フッターとマージン設定
$xlsSheet->getHeaderFooter()->setOddFooter('&C &P/' . $pages );
普通に考えれば上記のように書けばよさそうなものですが、
($pages には総ページ数を定義)
(&C は「中央寄せ」、&P は「現在のページ数を出力」)

処理は一貫しているのですが帳票がバラバラなので、
総ページ数はPHP側で算出できるのですが、
現在のページ数について、エクセルの側で逐一リセットされます。

1/5(総合計帳票)
1/5(明細帳票1_1ページ目)
2/5(明細帳票1_2ページ目)
1/5(明細帳票2_1ページ目)
1/5(明細帳票3_1ページ目)

こんな感じの出力になってしまいます。
なので、「その明細帳票が何ページ目からスタートするのか」を、
どうにか算出して持たせる必要があります。

$xlsSheet->getHeaderFooter()->setOddFooter('&C &P&+' . $cpage . '/' . $pages );

&+が「ページ番号に加える」処理とのことだったので、
現在のページ数に$cpage(当該帳票のスタートのページ数)を加算。

で、結果を確認してみましょう。




なんということでしょう。
「1(現在のページ数)2(当該帳票のスタートのページ数)/5(総ページ数)」
という出力に。

ちなみに、PDFでDLしているため上記の表記になっていますが、
PDFに書き換える前のxlsの状態でDLすると、意図した通りの採番出力になっていました。
なので、ここでは「書き方は間違っていないが処理が誤っている」という結論に。
(今思えば、書き方が間違っている可能性も多分にありますが)

しばらくネットの海を彷徨っていると、
「エクセルのページの開始番号を変更する」ことがPHPExcelで出来るらしい、と。
$xlsSheet->getPageSetup()->setFirstPageNumber((int)$cpage);
上記で試してみました。

ダメでした。
今度はxlsの時点で設定が適用されていない。

ここでPHPExcelのコアファイルをgrepしてみましょう。

$ pwd
/var/www/html/test/lib/PHPExcel
$ grep -rn firstPageNumber .
./Reader/Excel2007.php:1144:                                                            if (isset($xmlSheet->pageSetup["firstPageNumber"]) && isset($xmlSheet->pageSetup["useFirstPageNumber"]) &&
./Reader/Excel2007.php:1146:                                                                    $docPageSetup->setFirstPageNumber(intval($xmlSheet->pageSetup["firstPageNumber"]));
./Writer/Excel2007/Worksheet.php:862:                   $objWriter->writeAttribute('firstPageNumber',   $pSheet->getPageSetup()->getFirstPageNumber());
./Worksheet/PageSetup.php:275:  private $_firstPageNumber = NULL;
./Worksheet/PageSetup.php:762:          return $this->_firstPageNumber;
./Worksheet/PageSetup.php:772:          $this->_firstPageNumber = $value;

なんということでしょう。
注目すべきは「Reader」ディレクトリ以下のファイルです。
「Excel2007.php」に対し、処理の記述が確認出来ますね。
これ、テンプレートが「xlsx」のときに動作するファイルなんですよ。
今回のように「xls」テンプレートに対しては「Excel5.php」というコードが働くのですが、
「Excel5.php」に対しては「firstPageNumber」変数に関するコアの記述は無いようです。
つまり、「setFirstPageNumber()」でページの開始番号をセットしたつもりでも、
「xls」テンプレート向けには無駄だよ、と。
なんてこったい。

結局、今回はフッタ利用は諦め、
シート本体のフッタっぽい位置に現在のページ番号と総ページ数を記述する処理で逃げるという。

なんかやりようがある気はするんですが、今回はダメだったよ...