TechNote

事務屋のおぼえがき

PHPExcelでExcel作成~クライアント端末へコピー つまずいたことメモ

業務システムでよく必要となる以下の機能を実装しようとしてつまずいたことを今後の参考のためにメモ。

1.サーバ上の所定のフォルダへExcelファイルを作成する(PHPExcel5使用)
2.操作しているクライアント端末へExcelファイルをコピーし、起動する(VBScript使用)

1.サーバ上の所定のフォルダへExcelファイルを作成する(PHPExcel5使用)

用意しておいたひな形ExcelファイルをPHPExcelでオープン~値をセット~使用行に罫線を引く~名前を付けて保存。(保存ダイアログは表示させない)

//ループ処理などは省略、単純なセット方法のみのメモ

$this->load->library("phpexcel");
$objReader = new PHPExcel_Reader_Excel5();

$objPHPExcel = $objReader->load("d:\\conference_output\\gen\\format.xls");
$objPHPExcel->setActiveSheetIndex(0)->setCellValue('E2', $p_id);
$objPHPExcel->setActiveSheetIndex(0)->setCellValue('N2', $p_name);

//罫線
$objPHPExcel->setActiveSheetIndex(0)->getStyle('A'.$setrow.':'.'S'.$setrow)->getBorders()->getBottom()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
$objPHPExcel->setActiveSheetIndex(0)->getStyle('A'.$setrow)->getBorders()->getLeft()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
$objPHPExcel->setActiveSheetIndex(0)->getStyle('C'.$setrow)->getBorders()->getRight()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
$objPHPExcel->setActiveSheetIndex(0)->getStyle('F'.$setrow)->getBorders()->getRight()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
$objPHPExcel->setActiveSheetIndex(0)->getStyle('H'.$setrow)->getBorders()->getRight()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
$objPHPExcel->setActiveSheetIndex(0)->getStyle('S'.$setrow)->getBorders()->getRight()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);

//文字数や改行数に応じて行高さ設定
if($j > 3){
 $AdmRowHeight = $j * 20;
 $objPHPExcel->setActiveSheetIndex(0)->getRowDimension(6)->setRowHeight($AdmRowHeight);
}
$k = substr_count($soudannaiyou,"\n");
if($k > 3){
 $SDNRowHeight = $k * 20;
 $objPHPExcel->setActiveSheetIndex(0)->getRowDimension($setrow)->setRowHeight($SDNRowHeight);
}

//印刷範囲の設定
$objPHPExcel->getActiveSheet()->getPageSetup()->setPrintArea('A1:S'.$setrow);
$objPHPExcel->getActiveSheet()->setTitle('Output');
$objPHPExcel->setActiveSheetIndex(0);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter->save('d:\\conference_output\\ticket.xls');

ここまでは問題ないが、今回このひな形となるExcelファイルを数パターン用意しており、フラグによって使用するひな形Excelを使い分けるという仕様であった。その中の一つにチェックボックスを含むひな形があり、ここで問題発生。

チェックボックスを含む場合に、PHPExcelを通して編集をかけたらチェックボックスがすべて消えてしまう現象。ググってみると、PHPExcelやExcelWriterではチェックボックスに対応していないとのこと。

そこでCOMを使用した方法に変更すると解決。

$excel=new COM("excel.application") or die("システムエラーが発生したため処理を中止します。");
$excel->DisplayAlerts=0;
$sFilename = "d:\\conference_output\\can\\format.xls";

//ひな形段階で日本語シート名としていたらうまくいかないためここで命名
$sheet1_name = mb_convert_encoding("しーと名1","sjis-win","utf8");
$sheet2_name = mb_convert_encoding("しーと名2","sjis-win","utf8");

$wkb=$excel->Workbooks->Open($sFilename);
//シート1名称変更
$sheet=$wkb->Worksheets("sheet1");
$sheet->activate;
$sheet->Name=$sheet1_name;

$cells=$sheet->Cells(9,3);
$cells->Activate;
$cells->value=$p_id;

$cells=$sheet->Cells(11,3);
$cells->Activate;
$cells->value=mb_convert_encoding($patientname,"sjis-win","utf8");

//シート2名称変更
$sheet=$wkb->Worksheets("sheet2");
$sheet->activate;
$sheet->Name=$sheet2_name;

$cells=$sheet->Cells(9,3);
$cells->Activate;
$cells->value=$p_id;

//シート1アクティブ
$sheet=$wkb->Worksheets($sheet1_name);
$sheet->activate;

$wkb->SaveAs("d:\\conference_output\\ticket.xls");

$wkb->Close();
$excel->Quit();
unset($excel);
ちなみにハマり途中に試行錯誤したこと。
(1)PHPExcel5にパッチをあてる

・当初、チェックボックスを含むひな形の場合のみ、PHPExcelの「getNestingLevel」というところでエラーがでていた。そのエラーを検索したところ、解消するパッチが出ているとのこと。その手順は下記の通り。

①下記よりパッチをダウンロード
http://phpexcel.codeplex.com/SourceControl/list/patches

②更に、環境がWindowsなのでpatchコマンドを使用できるようにするため下記をダウンロード
http://gnuwin32.sourceforge.net/packages/patch.htm
③所定のフォルダへ配置
④パッチ適用

当初はこのような状態
f:id:kojikoji75:20130610122807p:plain
ここへfix.patchを配置
f:id:kojikoji75:20130610122813p:plain
コマンド実行

patch < パッチ

このとき、管理者権限でコマンドプロンプトを起動しないと処理は動かない。
f:id:kojikoji75:20130610122757p:plain
成功するとこのような状態となる
f:id:kojikoji75:20130610122819p:plain

⇒ここで初めて動作するようにはなったが、チェックボックスがなくなることに気付く。

(2)サーバのOfficeのバージョン

サーバー側のOfficeのバージョンも関係あるのか(Office2000)などと考え、Office2007を入れてみた。記述も「$objReader = new PHPExcel_Reader_Excel2007();」とした。
⇒別のエラーがでた。エラー内容は失念したが、解決がより困難そうな気がしたので5使用へ方針を戻す。

(3)COM使用でコードを書きなおすと解決。

2.操作端末へExcelファイルをコピーし、起動する(VBScript使用)

<script language="VBScript">
<!--
Function getFiletoCliant()

    Set objNetWork = CreateObject("WScript.Network")
    getComputerName = objNetWork.ComputerName
    Set objNetWork = Nothing

	path0="\\srvname\d\conference_output\ticket.xls"
	path1="\\" & getComputerName & "\C$\test\"
	filename="てすと.xls"

	Set fso = CreateObject("Scripting.FileSystemObject")
	Call fso.CopyFile(path0,path1,True)

	if fso.FileExists(path1 & filename) then
		fso.DeleteFile path1 & filename
	end if

	Set f = fso.getFile(path1 & "\ticket.xls")
	f.name = "てすと.xls"

    Set ExlApp = CreateObject("Excel.Application")
    ExlApp.Visible = True
    ExlApp.Workbooks.Open (path1 & filename)
	ExlApp.WindowState=-4143
	
	//最前面に表示
	CreateObject("WScript.Shell").SendKeys "%({TAB})"

	Set ExlApp = nothing

End Function

-->
</script>

あわせて読みたい

PEAR コマンドプロンプトから必要モジュールのインストール方法 - TechNotePEAR コマンドプロンプトから必要モジュールのインストール方法 - TechNote

XAMPP使用の場合、PEARはある程度のモジュールは入っている。それ以外で必要なモジュールがでてきた場合は、ネット環境でコマンドプロンプトにて下記を実行すると...

シングルクォーテーションとダブルクォーテーションの使い分けの例 - TechNoteシングルクォーテーションとダブルクォーテーションの使い分けの例 - TechNote

$number = 100;echo "変数の値は $number です";echo '変数名は $number です';徹底攻略 PHP5技術者認定[初級]試...

PHP COMでExcel操作例 - TechNotePHP COMでExcel操作例 - TechNote

// EXCELのインスタンス作成$excel = new COM("excel.application") or die;$excel->DisplayAle...

プログラムで簡単理解! 7つの超重要な整列アルゴリズム(ソートアルゴリズム)まとめ - TechNoteプログラムで簡単理解! 7つの超重要な整列アルゴリズム(ソートアルゴリズム)まとめ - TechNote

基本情報技術者試験や応用情報技術者試験の時期も近まった今、あらためて整列アルゴリズムをまとめてみたので、忘備録を兼ねてメモを残します。即席コードも併せて記載しま...


Excel+PHP Webデータベース開発 Excel 2000~2003・2007対応 (VBA for Professionals)

Excel+PHP Webデータベース開発 Excel 2000~2003・2007対応 (VBA for Professionals)