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

PHP
スポンサーリンク

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

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>
Excel+PHP Webデータベース開発 Excel 2000~2003・2007対応 (VBA for Professionals)

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

タイトルとURLをコピーしました