web-dev-qa-db-ja.com

PDFファイルをHTMLリンクでダウンロード可能にするにはどうすればいいですか?

下記のように、私はダウンロードのために私のウェブページ上のpdfファイルのリンクを与えています

<a href="myfile.pdf">Download Brochure</a>

問題は、ユーザーがこのリンクをクリックしたときです。

  • ユーザーがAdobe Acrobatをインストールした場合は、Adobe Readerの同じブラウザウィンドウでファイルを開きます。
  • Adobe Acrobatがインストールされていない場合は、ファイルをダウンロードするためのポップアップがユーザーに表示されます。

しかし、「Adobe acrobat」がインストールされているかどうかにかかわらず、ダウンロードのために常にポップアップ表示されるようにしたい.

私がこれを行うことができる方法を教えてください?

115
Prashant

.PDFファイルにリンクするのではなく、代わりに次のようにします。

<a href="pdf_server.php?file=pdffilename">Download my eBook</a>

カスタムヘッダーを出力し、PDF(バイナリセーフ)を開いてユーザーのブラウザにデータを印刷します。その後、ブラウザの設定にかかわらずPDFを保存することを選択できます。 pdf_server.phpは次のようになります。

header("Content-Type: application/octet-stream");

$file = $_GET["file"] .".pdf";
header("Content-Disposition: attachment; filename=" . urlencode($file));   
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");            
header("Content-Length: " . filesize($file));
flush(); // this doesn't really matter.
$fp = fopen($file, "r");
while (!feof($fp))
{
    echo fread($fp, 65536);
    flush(); // this is essential for large downloads
} 
fclose($fp); 

シモンズ:そして明らかに「ファイル」変数の健全性チェックを実行して、ファイル拡張子を受け入れない、スラッシュを拒否する、値に.pdfを追加するなど、人々があなたのファイルを盗むのを防ぐ

114
TravisO

これは一般的な問題ですが、単純なHTML 5ソリューションがあることを知っている人はほとんどいません。

<a href="./directory/yourfile.pdf" download="newfilename">Download the pdf</a>

newfilenameは、ユーザーがファイルを保存するための推奨ファイル名です。次のように空のままにしておくと、サーバーサイドのファイル名がデフォルトになります。

<a href="./directory/yourfile.pdf" download>Download the pdf</a>

互換性:私はFirefox 21とIronでこれをテストしました、両方ともうまくいきました。 HTML5非対応または古いブラウザでは動作しないかもしれません。ダウンロードを強制しなかった私がテストした唯一のブラウザはIEです...

ここで互換性をチェックしてください: http://caniuse.com/#feat=download

176
T_D

すべてのファイル行をループ処理しないでください。代わりにreadfileを使ってください。これはphpサイトから外れています。 http://php.net/manual/en/function.readfile.php

$file = $_GET["file"];
if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header("Content-Type: application/force-download");
    header('Content-Disposition: attachment; filename=' . urlencode(basename($file)));
    // header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    exit;
}

誰かがいくつかのphpファイルをダウンロードする可能性があるのであなたのget変数をサニタイズすることを忘れないでください...

49
Alex V

PHPスクリプトを使用してファイルを読み取ってフラッシュするのではなく、.htaccessを使用してヘッダーを書き直す方がきれいです。これは "Nice" URL(myfile.pdfの代わりにdownload.php?myfile)を保持します。

<FilesMatch "\.pdf$">
ForceType applicaton/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
25
Rob W

私は、普通のHTMLとJavaScript/jQueryを使って適切に機能を低下させる方法を見つけました。 IE7-10、Safari、Chrome、およびFFでテスト済み。

ダウンロードリンクのHTML:

<p>Thanks for downloading! If your download doesn't start shortly, 
<a id="downloadLink" href="...yourpdf.pdf" target="_blank" 
type="application/octet-stream" download="yourpdf.pdf">click here</a>.</p>

少し遅れてリンクをクリックするのをシミュレートするjQuery(純粋なJavaScriptコードのほうが冗長)

var delay = 3000;
window.setTimeout(function(){$('#downloadLink')[0].click();},delay);

これをより堅牢にするために、HTML5機能の検出を追加することができます。それがない場合は、window.open()を使用してファイルを含む新しいウィンドウを開きます。

15
Alex W

これが鍵です。

header("Content-Type: application/octet-stream");

PDFファイルの送信中に、コンテンツタイプapplication/x-pdf-documentまたはapplication/pdfが送信されます。 Adobe Readerは通常、このMIMEタイプのハンドラを設定するので、PDF MIMEタイプのいずれかを受信したときにブラウザはそのドキュメントをAdobe Readerに渡します。

6
Sudden Def

HTML5にはもっと簡単な方法があります:Download属性を追加します。

最近のほとんどのブラウザでサポートされています。

<a download href="file.pdf">Download PDF</a> 
5
tawsif torabi

私はこれに答えるのが非常に遅れていることを知っています、しかし私はJavaScriptでこれをするためのハックを見つけました。

function downloadFile(src){
    var link=document.createElement('a');
    document.body.appendChild(link);
    link.href= src;
    link.download = '';
    link.click();
}
4
Shivek Parmar

これを試して:

<a href="pdf_server_with_path.php?file=pdffilename&path=http://myurl.com/mypath/">Download my eBook</a>

Pdf_server_with_path.php内のコードは次のとおりです。

header("Content-Type: application/octet-stream");

$file = $_GET["file"] .".pdf";
$path = $_GET["path"];
$fullfile = $path.$file;

header("Content-Disposition: attachment; filename=" . Urlencode($file));   
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");            
header("Content-Length: " . Filesize($fullfile));
flush(); // this doesn't really matter.
$fp = fopen($fullfile, "r");
while (!feof($fp))
{
    echo fread($fp, 65536);
    flush(); // this is essential for large downloads
} 
fclose($fp);
0
Saill

ダウンロード速度を制限する必要がある場合は、このコードを使用してください。

<?php
$local_file = 'file.Zip';
$download_file = 'name.Zip';

// set the download rate limit (=> 20,5 kb/s)
$download_rate = 20.5;
if(file_exists($local_file) && is_file($local_file))
{
header('Cache-control: private');
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($local_file));
header('Content-Disposition: filename='.$download_file);

flush();
$file = fopen($local_file, "r");
while(!feof($file))
{
    // send the current file part to the browser
    print fread($file, round($download_rate * 1024));
    // flush the content to the browser
    flush();
    // sleep one second
    sleep(1);
}
fclose($file);}
else {
die('Error: The file '.$local_file.' does not exist!');
}

?>

詳しくは ここをクリック

0

私はPDFファイルのURL全体を使って解決しました(ファイル名または場所を単にhrefに入れる代わりに):a href = "domain。com/pdf/filename.pdf"

0
Mark Allena
<!DOCTYPE html>  
<html xmlns="http://www.w3.org/1999/xhtml">  
<head>  
    <title>File Uploader</title>  
    <script src="../Script/angular1.3.8.js"></script>  
    <script src="../Script/angular-route.js"></script>  
    <script src="../UserScript/MyApp.js"></script>  
    <script src="../UserScript/FileUploder.js"></script>  
    <>  
        .percent {  
            position: absolute;  
            width: 300px;  
            height: 14px;  
            z-index: 1;  
            text-align: center;  
            font-size: 0.8em;  
            color: white;  
        }  

        .progress-bar {  
            width: 300px;  
            height: 14px;  
            border-radius: 10px;  
            border: 1px solid #CCC;  
            background-image: -webkit-gradient(linear, left top, left bottom, from(#6666cc), to(#4b4b95));  
            border-image: initial;  
        }  

        .uploaded {  
            padding: 0;  
            height: 14px;  
            border-radius: 10px;  
            background-image: -webkit-gradient(linear, left top, left bottom, from(#66cc00), to(#4b9500));  
            border-image: initial;  
        }  
    </>  
</head>  
<body ng-app="MyApp" ng-controller="FileUploder">  
    <div>  
        <table ="width:100%;border:solid;">  
            <tr>  
                <td>Select File</td>  
                <td>  
                    <input type="file" ng-model-instant id="fileToUpload" onchange="angular.element(this).scope().setFiles(this)" />  
                </td>  
            </tr>  
            <tr>  
                <td>File Size</td>  
                <td>  
                    <div ng-repeat="file in files.slice(0)">  
                        <span ng-switch="file.size > 1024*1024">  
                            <span ng-switch-when="true">{{file.size / 1024 / 1024 | number:2}} MB</span>  
                            <span ng-switch-default>{{file.size / 1024 | number:2}} kB</span>  
                        </span>  
                    </div>  
                </td>  
            </tr>             
            <tr>  
                <td>  
                    File Attach Status  
                </td>  
                <td>{{AttachStatus}}</td>  
            </tr>  
            <tr>  
                <td>  
                    <input type="button" value="Upload" ng-click="fnUpload();" />  
                </td>  
                <td>  
                    <input type="button" value="DownLoad" ng-click="fnDownLoad();" />  
                </td>  
            </tr>  
        </table>  
    </div>  
</body>  
</html>   
0
user11021789

これは別のアプローチです。 Webサーバーロジックを使用するには、ブラウザのサポートに頼るよりも、アプリケーション層でこれに対処するよりも優先します。

Apacheを使用していて、関連するディレクトリに.htaccessファイルを置くことができるなら、あなたは以下のコードを使うことができます。もちろん、アクセス可能であれば、これをhttpd.confに入れることもできます。

<FilesMatch "\.(?i:pdf)$">
  Header set Content-Disposition attachment
</FilesMatch>

FilesMatchディレクティブは単なる正規表現なので、必要に応じてきめ細かく設定することも、他の拡張子を追加することもできます。

Header行は、上記のPHPスクリプトの最初の行と同じことを行います。あなたが同様にContent-Type行を設定する必要があるなら、あなたは同じ方法でそうすることができます、しかし、私はそれが必要であるとわかりませんでした。

0
Evan Donovan