LoginSignup
6
2

More than 3 years have passed since last update.

PDFのブラウザ表示・ダウンロード

Last updated at Posted at 2020-03-12

まず単純にボタンを押してPDFファイルをダウンロードする場合の
ダウンロードファイル名は以下のようにContent-Dispositionヘッダを
attachmentにし、filenameを設定することで可能です。

PdfSample.php
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Length: ' . filesize($file_path));
readfile($file_path);

今回の要件では、
ブラウザで表示した上で、もしユーザによってダウンロードされた場合の
ファイル名を設定することなので、以下のようにattachmentをinlineに変更します。

PdfSample.php
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Length: ' . filesize($file_path));
readfile($file_path);

これでブラウザでの表示はできましたが、
いくつかのブラウザでダウンロード時のファイル名が正しく設定されませんでした。

そこでいくつかリクエスト時の処理を変更していきました。

1.POSTメソッドではなくGETメソッドを使用する。

もともとPOSTメソッドでファイルNoを渡してPHP側でそのファイルNoに紐づく
ファイルを表示させるという処理を行っていたのですが、
Chromeでダウンロード時のファイル名が上手く設定されませんでした。
そこでGETメソッドに変えることでChromeでの動作が確認できました。

2.URLの最終の「/」以下をダウンロード時のファイル名にする

①でChromeは動作確認がとれましたが、
今度はIE、Edgeでダウンロードする時に「無題.pdf」のような名前になってしまいました。
IEやEdgeではどうやらContent-dispositoionをinlineにした場合に、
filenameでの設定が上手くいかない場合があるようです。
調べていくと、URLの最終の「/」以下の部分がダウンロード時に有効とのことでした。
Laravelを使用している場合は、以下のようにルーティングを行います。

web.php
Route::get('/download/{download_name}', 'HoegeController@OpenPdf');

これでIEでの動作が確認できましたが、Edgeではやはり「無題.pdf」のようになりました。
この時GETパラメータとしてファイルNoを渡してPHP側で処理していましたが、
どうやらGETパラメータを渡すとEdgeでは正しくダウンロード名が設定できないようです。

3.GETパラメータを使用しない

実装時点では一旦②まで対応してEdgeは対象外としていたのですが、
よくよく考えたらGETパラメータの代わりに、
ルーティングのURL途中にファイルNoを入れることで
PHP側での処理が可能だったな思います。時間があるとき直したい。。。

web.php
Route::get('/download/{file_no}/{download_name}', 'HoegeController@OpenPdf');

以上になります。

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2