
前提・実現したいこと
CodeIgniter2を使ったWebシステムで、PDFを作るプログラムを作成しています。
目指している挙動は
- ユーザがダウンロードボタンを押す
- PHPでPDFを作成
- 作成したPDFを別ウインドウで表示
- 保存したければ保存してもらう
となります。
対象ブラウザはGoogleChromeのみです。
4.のPDFの保存は、ブラウザ上でPDFを表示した際に「ダウンロード」というアイコンが出るので、
その機能を使ってもらう予定にしています。
※指の形のカーソルが出てるアイコンの事です
発生している問題・エラーメッセージ
3のPDF表示までは上手くいっていますが、その後ダウンロードアイコンを押すと、
「失敗-ネットワークエラー-」と表示されてしまい、ダウンロードできません。
表示できているのにダウンロードで失敗する場合、どこを疑えばいいのかもよくわかっていない状態です。
ネットワークエラーと表示されているので何かしらPHPのプログラムに問題があるのでは?と調査しているのですが、有用な情報を見つけることができません。
また、ブラウザ上に表示されるファイル名(画像で塗りつぶしている箇所)について
下記ソースの通り「sample.pdf」になるのを期待していますが、実際にはパラメータ名(※1)になってしまっています。
ここに拡張子が付いていないのが問題かと思い、試しにパラメーターに.pdfを付けてみましたが、結果は同じでした。
どうすれば表示したPDFを保存できるようになるのでしょうか。
ブレイクポイントを設定してダウンロードアイコンを押してみましたが、PHPが呼ばれていなかったため、最初にPDFを表示した時のレスポンスの設定が怪しいと思い、該当箇所のソースを載せています。
見当違いの場合は、お手数ですが指摘して頂ければ助かります。
(※1)
CodeIgniterを使用しているので、パラメーターを渡す場合urlの関数名の後ろに/paramという形で加えます。
の場合、表示されるファイル名が「aaa」になってしまいます。
該当のソースコード
以下がPDFを返している処理です。
php
1function download($param){ 2 : 3 : 4 $html = $this->load->view(PDF化したいviewのパス, $result, TRUE); 5 $pdf = new Knp\Snappy\Pdf(wkhtmltopdfのパス); 6 $pdf->setOption('encoding', 'utf-8'); 7 $this->output 8 ->set_header('Content-Disposition: inline; filename="sample.pdf"') 9 ->set_content_type("application/pdf") 10 ->set_output($pdf->getOutputFromHtml($html)); 11}
試したこと
その1
PDFに問題があるのか調査するため、Content-Dispositionをattachmentにしてどうなるか試してみました。
php
1function download($param){ 2 : 3 : 4 $this->output 5 ->set_header('Content-Disposition: attachment; filename="sample.pdf"') 6 ->set_content_type("application/pdf") 7 ->set_output($pdf->getOutputFromHtml($html)); 8}
ファイルがダウンロードされ、開くこともできました。
一応ダウンロードアイコンを押してみましたが、ちゃんとダウンロードできました。
その2
作成したPDFは実体のファイルになっていないのが原因ではないかと思い、
一旦サーバーに実ファイルを作成して、ファイルをダウンロードするようにしてみました。
php
1function download($param){ 2 : 3 $this->load->helper('file'); 4 $data = read_file("作成したPDFファイルのパス"); 5 6 $this->output 7 ->set_header('Content-Disposition: inline; filename="sample.pdf"') 8 ->set_content_type("application/pdf") 9 ->set_output($data); 10}
実ファイルを作成する前と同様、
ファイルの内容は表示されるけど、ダウンロードを押すとネットワークエラーになってしまいました。
またブラウザ上に表示されるファイル名もsample.pdfではなくパラメーター名になってしまいました。
(追記) 解決した設定
asahina1979さんにご指摘頂いて、作成したPDFがキャッシュされるように指定を加えました。
php
1 $this->output 2 ->set_content_type("application/pdf") 3 ->set_header('Content-Disposition: inline; filename=sample.pdf') 4// 追加ここから 5 ->set_header('Last-Modified: Fri Jan 01 2010 00:00:00 GMT') 6 ->set_header('Expires: Fri Jan 01 2019 00:00:00 GMT') // お試しで未来日を入れる 7 ->set_header('Cache-Control: private, max-age=86400') // お試しで1日にしてみる 8// 追加ここまで 9 ->set_output($pdf->getOutputFromHtml($html));
インラインで表示後ダウンロードアイコンを押して正常にダウンロードされるようになりました。
ファイル名についてもキャッシュの設定を加えることで反映されるようになり、sample.pdfとしてダウンロードできました。
ありがとうございました!
補足情報(FW/ツールのバージョンなど)
PHP 7.1
CodeIgniter 2
GoogleChrome
wkhtmltopdf(PDF作成用)
Snappy(PDF作成の元ネタHTML作成用)





回答1件
あなたの回答
tips
プレビュー