PHPExcel : してログ

PHPExcel はとにかく遅いし、バグも多いのでできれば使いたくないですよね。 でも、xlsx に出すなら使うしかなくて、そんなときはおっかなびっくり使うしか無い、です。 さて、今日はこのエラー「Maximum 31 characters allowed in sheet title」が唐突に出るようになりました。

メッセージからすると、31文字を超えるシート名は使えない、ということになろうかと思います。 しかし、正しく処理できていたエクセルファイルを保存しなおしただけで、このエラーが出るようになったので、訳が分かりません。 念のため、すべてのシートの文字数をチェックしましたが、31文字を超えるものはありませんでした。 Google 先生に聞いてみると、ライブラリに応急手当てして無理やり出ないようにしたという記事が幾つかみつかります。 原因はともかく、私もそれに習って修正してみました。

Classes/PHPExcel/Worksheet.php
	public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = true)
	{
		$pValue = substr($pValue, 0, 31); // この行を追加

(追記)この対応をすると、iconv でマルチバイト文字が正しくないというエラーが出ますので、やめた方が良いです。 詳しくは分かりませんが、元のエラーはメモリ不足で出ていたように思います。

単純なワークシートのコピーで、下記のようなエラーが出ました。 コードを最小化しても出続けるみたいなので、試しに 1.7.8 にバージョンを下げてみたところ解決しました。 とりあえず、PHPExcel 1.7.9 は封印したほうが良いかも知れません。

Catchable fatal error: Argument 1 passed to PHPExcel_Cell::attach() must be an instance of PHPExcel_CachedObjectStorage_CacheBase, instance of PHPExcel_Worksheet given, called in C:\wk\bousai3\_cmn\PHPExcel_1.7.9\Classes\PHPExcel\CachedObjectStorage\Memory.php on line 99 and defined in C:\wk\bousai3\_cmn\PHPExcel_1.7.9\Classes\PHPExcel\Cell.php on line 115

エクセルのセル番号「A1」とか、アルファベットが列、数字が行というやつ。 アルファベットの部分をプログラムで扱う場合は、数字で管理しないとやりにくい。 そこで今日、その変換ルーチンを書いていたんですが、どうもうまくいかない。 二桁程度だとロジックも簡単なのだが、一般化しようと思って任意の桁に拡大した途端、難易度が段違いに上がる。 というか、断念してしまいました。

基本は、アルファベット26文字による26進数への変換となるはずなのですが、そうすると A~Z までは OK、その次が BA となる。 なぜかというと、ゼロが無いから。 よく考えると、ゼロのない26進数となっているのだが、アルファベット表記なため、それに気づきにくい。 話を簡単にするために、1~3 のゼロなし3進数とすると、1、2、3、11、12、13、21... というような並びになる。 従って、ゼロのある頭でロジックを考えた結果、Z の次が BA になる訳だ。

というところまで分かって、ゼロなしの26進数への変換ロジックを考えてみる。 これが、予想以上に難解で3桁の直前の YZ までできる関数しか出来ませんでした。 ので、ソースはありません。

代わりに、PHPExcel のスタティック関数(PHPExcel_Cell::stringFromColumnIndex)を使うことにしました。 PHPExcel のライブラリをインクルードすれば、静的関数なのですぐに使えます。 今度、ソースコードを覗いて、どんなロジックで変換しているのか勉強してみようと思います。