質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

3回答

13086閲覧

PHPExcelでexcelへの書き込み

ao_love

総合スコア441

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2016/11/01 10:23

編集2016/11/02 02:34

お世話になっております。
PHPExcelによるエクセルDLについてお尋ねです。

###前提・実現したいこと
PHPExcelでテンプレート読み込み

DBから取得したデータを書き込み

書き込んだエクセルのDL

書き込みの量としては最大でも20行15列程度。
3行15列程度でテストしています。

###発生している問題・エラーメッセージ
ローカルのxammpp,サーバー1では問題なく行えていたDLがサーバー2ではできなくなった。
500サーバーエラーが発生し、PHPのエラーなどの表示は出ません。

DLではなく出力する方法でも同じです。

###該当のソースコード

PHP

1//ディレクトリ設定 2$dir = '.'; 3 4//ライブラリ読み込み 5require_once $dir . '/Classes/PHPExcel.php'; 6require_once $dir . '/Classes/PHPExcel/IOFactory.php'; 7 8//テンプレート読み込み 9$file = $dir.'/temp.xlsx';//テンプレート名 10$reader = PHPExcel_IOFactory::createReader('Excel2007'); 11$book = $reader->load($file); 12 13// $_SESSIONから読み込み 14session_start(); 15$term_id = $_SESSION["term_id"]; 16$term_name = $_SESSION["term_name"]; 17$ticket = $_SESSION["ticket"]; 18 19// シート名をDBから取得して設定 20$sql = "SELECT year,month,place,first_date FROM term ORDER BY id DESC LIMIT 1"; 21$res = $conDB->pdoQuery($sql); 22$year = $res[0]['year']; 23$month = $res[0]['month']; 24$place = $res[0]['place']; 25$first = $res[0]['first_date']; 26 27// 前売テーブルから最新期間の情報を取得 28$sql = "SELECT * FROM advance WHERE term_id = ".$term_id; 29$res = $conDB->pdoQuery($sql); 30foreach ($res as $value) { 31 $ad_arr[$value["ticket_id"]] = $value; 32} 33 34 35//シートを設定する 36$book->setActiveSheetIndex(0);//一番最初のシートを選択(2枚目なら(1)) 37$sheet = $book->getActiveSheet();//選択シートにアクセスを開始 38$sheet->setTitle( $year.'年'.$month.'月' ); //シート名を設定、変数OK 39 40 41/************************ 42 * シート書き込み内容設定 43 ***********************/ 44// 現在の状況の書き込み 45$col = 3; 46foreach ($ad_arr as $tid=>$value){ 47 $sheet->setCellValueByColumnAndRow(0,$col,$tid); 48 $sheet->setCellValueByColumnAndRow(1,$col,$ticket[$tid]["name"]); 49 $sheet->setCellValueByColumnAndRow(2,$col,$value["1st"]); 50 $sheet->setCellValueByColumnAndRow(3,$col,$value["2nd"]); 51 $sheet->setCellValueByColumnAndRow(4,$col,$value["3rd"]); 52 $sheet->setCellValueByColumnAndRow(5,$col,$value["4th"]); 53 $sheet->setCellValueByColumnAndRow(6,$col,$value["5th"]); 54 $sheet->setCellValueByColumnAndRow(7,$col,$value["6th"]); 55 $sheet->setCellValueByColumnAndRow(8,$col,$value["7th"]); 56 $sheet->setCellValueByColumnAndRow(9,$col,$value["8th"]); 57 $sheet->setCellValueByColumnAndRow(10,$col,$value["9th"]); 58 $sheet->setCellValueByColumnAndRow(11,$col,$value["10th"]); 59 $sheet->setCellValueByColumnAndRow(12,$col,$value["11th"]); 60 $sheet->setCellValueByColumnAndRow(13,$col,$value["12th"]); 61 $sheet->setCellValueByColumnAndRow(14,$col,$value["13th"]); 62 $sheet->setCellValueByColumnAndRow(15,$col,$value["14th"]); 63 $sheet->setCellValueByColumnAndRow(16,$col,$value["15th"]); 64 65 $col++; 66} 67 68// 日付の書き込み 69for ($i=0; $i < 15; $i++) { 70 $date = $month."月".($first+$i)."日"; 71 $sheet->setCellValueByColumnAndRow($i+2,2,$date); 72} 73 74/************** 75 * 出力処理 76 **************/ 77//出力ファイル名の設定(拡張子は出力形式に合わせて変える) 78$output = 'output_'.$year.'_'.$month.'.xlsx'; 79 80// Excel2007形式(xlsx)で出力する 81$writer = PHPExcel_IOFactory::createWriter($book, 'Excel2007'); 82$writer->save($output);

###試したこと
とりあえずは問題の切り分けということでソースを細切れにして実行してみたところ
最後の$writer->save('php://output');があるとエラーになります。
その直前まではvar_dump等で変数の出力も問題なく行えています。

以下の環境の通り、実行したいサーバー2はメモリがかなり小さいので対策としてテンプレート読み込みの前に

php

1$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp; 2$cacheSettings = array('dir' => '/tmp'); 3PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);

を挿入して実行してみましたが状況は変わりませんでした。
読み込みの時点では処理は止まらず、
Fatal error: Allowed memory size of ~~の様なエラーもでていません。

PHP

1$writer->save($output); 2exit();

にもしてみましたがやはり同様でした。

###補足情報(言語/FW/ツール等のバージョンなど)
各環境は以下です

######xampp(DL・出力できる)
XAMPP:for Windows 5.6.23
Apache:2.4.17
PHP:5.6.23
mysql:Ver 15.1 Distrib 10.1.13-MariaDB

サーバー1(DL・出力できる)

OS:Turbolinux Appliance Server 3.0
Apache:2.2.6
PHP:5.2.4
mysql:5.0.45

サーバー2(DLも出力もできない)

OS:CentOS7.2
Apache:2.4.6
PHP:7.0.12
mysql:5.6.34

GMOALTUSのミニサーバーなので1コア1CPUのメモリ512MB

追記

seastar3さんからのご回答で肝心のDL仕様のコードを載せていないことに気づきましたので追記させていただきます。

PHP

1// DLさせるときはこちらを使用 2// header('Content-Type: application/force-download'); #1 3// header('Content-Type: application/vnd.ms-excel'); #2 4header('Content-Type: application/octet-stream')5ob_end_clean();//バッファのゴミ捨て 6header('Content-Disposition: attachment;filename='.$output); 7header('Cache-Control: max-age=0'); 8 9$writer = PHPExcel_IOFactory::createWriter($book, "Excel2007"); 10$writer->save('php://output'); 11exit();

Content-Typeについてはコメントアウトしてあるものも含めてすべて試してみましたがすべて同じ結果でした。
動きとしては他ページのボタンからtarget="_blrank"でリンクしています。
$writer->save('php://output');
をコメントアウトするとシート名の正しい空のエクセルが出力されます…。

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

自己解決

PHPのバージョンの影響でした。
PHP7以降ではloopswitch内以外でbreakを利用するとエラーになるため。

Classes/PHPExcel/Calculation/Functions.php
の581行目にある
break;
のコメントアウトで期待の結果が得られました。

投稿2016/12/13 06:18

ao_love

総合スコア441

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

バッファのクリアが必要なのではないでしょうか。

ob_end_clean(); ```をsave()メソッドを使う前に仕込んでみるといけるかも知れません。 私の体験ですが、PHPExcelを活用して Excelワークシートに保存したファイルのダウンロード操作で、 ```ここに言語を入力 readfile(Excelブック名, FILE_BINARY); ```を記述する前に ```ここに言語を入力 ob_end_clean(); ```と入れるまで、破損したファイルが保存されて苦労したことがあります。

投稿2016/11/01 12:40

seastar3

総合スコア2285

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ao_love

2016/11/02 02:23

ありがとうございます。 私も以前そのトラップにハマって、ob_end_clean(); を追記したのに、転記し忘れていたようです…(^^; 基本やりたいのはDLさせることなので追記したものを使用しています。
guest

0

$writer->save('php://output');があるとエラーになります。

具体的にどんなエラーなのでしょうか?

投稿2016/11/01 11:15

yambejp

総合スコア114572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ao_love

2016/11/02 02:25

エラーは500メッセージです。 PHPのエラーをはいてくれれば対処しやすいのですが>< ちなみにchromeだと【一時的に停止しているか、新しいウェブアドレスに移動した可能性があります】 Firefoxだと【ファイルが見つかりませんでした】というメッセージです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問