简体   繁体   English

如何使 PDF 文件可在 HTML 链接中下载?

[英]How to make PDF file downloadable in HTML link?

I am giving link of a pdf file on my web page for download, like below我在我的网页上提供 pdf 文件的链接以供下载,如下所示

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

The problem is when user clicks on this link then问题是当用户点击这个链接时

  • If the user have installed Adobe Acrobat, then it opens the file in the same browser window in Adobe Reader.如果用户已安装 Adob​​e Acrobat,则它会在 Adob​​e Reader 的同一浏览器窗口中打开文件。
  • If the Adobe Acrobat is not installed then it pop-up to the user for Downloading the file.如果未安装 Adob​​e Acrobat,则会向用户弹出下载文件。

But I want it always pop-up to the user for download, irrespective of "Adobe acrobat" is installed or not.但我希望它总是弹出给用户下载,无论是否安装了“Adobe acrobat”。

Please tell me how i can do this?请告诉我我该怎么做?

This is a common issue but few people know there's a simple HTML 5 solution:这是一个常见问题,但很少有人知道有一个简单的 HTML 5 解决方案:

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

Where newfilename is the suggested filename for the user to save the file.其中newfilename是用户保存文件的建议文件名。 Or it will default to the filename on the serverside if you leave it empty, like this:或者如果您将其留空,它将默认为服务器端的文件名,如下所示:

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

Compatibility: I tested this on Firefox 21 and Iron, both worked fine.兼容性:我在 Firefox 21 和 Iron 上对此进行了测试,两者都运行良好。 It might not work on HTML5-incompatible or outdated browsers.它可能不适用于与 HTML5 不兼容或过时的浏览器。 The only browser I tested that didn't force download is IE...我测试过的唯一没有强制下载的浏览器是 IE...

Check compatibility here: http://caniuse.com/#feat=download在此处检查兼容性: http : //caniuse.com/#feat=download

Instead of linking to the .PDF file, instead do something like与其链接到 .PDF 文件,不如执行类似的操作

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

which outputs a custom header, opens the PDF (binary safe) and prints the data to the user's browser, then they can choose to save the PDF despite their browser settings.它输出自定义标题,打开 PDF(二进制安全)并将数据打印到用户的浏览器,然后他们可以选择保存 PDF,而不管他们的浏览器设置。 The pdf_server.php should look like this: 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); 

PS: and obviously run some sanity checks on the "file" variable to prevent people from stealing your files such as don't accept file extensions, deny slashes, add .pdf to the value PS:显然对“文件”变量运行一些健全性检查以防止人们窃取您的文件,例如不接受文件扩展名,拒绝斜杠,将 .pdf 添加到值中

Don't loop through every file line.不要遍历每个文件行。 Use readfile instead, its faster.改用readfile ,它更快。 This is off the php site: http://php.net/manual/en/function.readfile.php这是 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;
}

Make sure to sanitize your get variable as someone could download some php files...确保清理你的 get 变量,因为有人可以下载一些 php 文件......

Instead of using a PHP script, to read and flush the file, it's more neat to rewrite the header using .htaccess .使用.htaccess重写头文件而不是使用 PHP 脚本来读取和刷新文件。 This will keep a "nice" URL ( myfile.pdf instead of download.php?myfile ).这将保留一个“不错”的 URL( myfile.pdf而不是download.php?myfile )。

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

I found a way to do it with plain old HTML and JavaScript/jQuery that degrades gracefully.我找到了一种使用普通旧 HTML 和 JavaScript/jQuery 优雅降级的方法。 Tested in IE7-10, Safari, Chrome, and FF:在 IE7-10、Safari、Chrome 和 FF 中测试:

HTML for download link:下载链接的 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 (pure JavaScript code would be more verbose) that simulates clicking on link after a small delay: jQuery(纯 JavaScript 代码会更冗长)模拟在一小段延迟后点击链接:

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

To make this more robust you could add HTML5 feature detection and if it's not there then use window.open() to open a new window with the file.为了使其更健壮,您可以添加 HTML5 功能检测,如果不存在,则使用window.open()打开一个包含该文件的新窗口。

This is the key:这是关键:

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

Content-type application/x-pdf-document or application/pdf is sent while sending PDF file.内容类型 application/x-pdf-document 或 application/pdf 在发送 PDF 文件时发送。 Adobe Reader usually sets the handler for this MIME type so browser will pass the document to Adobe Reader when any of PDF MIME types is received. Adobe Reader 通常会为此 MIME 类型设置处理程序,因此当接收到任何 PDF MIME 类型时,浏览器会将文档传递给 Adob​​e Reader。

There is an easier way in HTML5: Add a Download attribute. HTML5中有一种更简单的方法:添加Download属性。

It is supported by most of the modern browsers. 大多数现代浏览器都支持它。

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

I know I am very late to answer this but I found a hack to do this in javascript.我知道我回答这个问题已经很晚了,但我发现了一个在 javascript 中做到这一点的技巧。

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

This can be achieved using HTML.这可以使用 HTML 来实现。

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

Add download attribute to it: Here the file name will be myfile.pdf添加下载属性:这里的文件名将是 myfile.pdf

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

Specify a value for the download attribute:为下载属性指定一个值:

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

Here the file name will be Brochure.pdf这里的文件名将是 Brochure.pdf

Try this:试试这个:

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

The code inside pdf_server_with_path.php is: 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);

Here's a different approach.这是一种不同的方法。 I prefer rather than to rely on browser support, or address this at the application layer, to use web server logic.我更喜欢使用 Web 服务器逻辑而不是依赖浏览器支持或在应用程序层解决这个问题。

If you are using Apache, and can put an .htaccess file in the relevant directory you could use the code below.如果您使用的是 Apache,并且可以将 .htaccess 文件放在相关目录中,则可以使用以下代码。 Of course, you could put this in httpd.conf as well, if you have access to that.当然,如果您可以访问它,您也可以将它放在 httpd.conf 中。

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

The FilesMatch directive is just a regex so it could be set as granularly as you want, or you could add in other extensions. FilesMatch 指令只是一个正则表达式,因此可以根据需要进行精细设置,或者您可以添加其他扩展名。

The Header line does the same thing as the first line in the PHP scripts above. Header 行与上述 PHP 脚本中的第一行执行相同的操作。 If you need to set the Content-Type lines as well, you could do so in the same manner, but I haven't found that necessary.如果您还需要设置 Content-Type 行,您可以以相同的方式进行设置,但我认为没有必要这样做。

我使用 PDF 文件的整个 url 解决了我的问题(而不仅仅是将文件名或位置放在 href 中):a href="domain . com/pdf/filename.pdf"

if you need to limit download rate, use this code !!如果您需要限制下载速率,请使用此代码!

<?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!');
}

?>

For more information click here欲了解更多信息,请单击此处

<!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>   

In a Ruby on Rails application (especially with something like the Prawn gem and the Prawnto Rails plugin), you can accomplish this a little more simply than a full on script (like the previous PHP example).在 Ruby on Rails 应用程序中(尤其是使用 Prawn gem 和 Prawnto Rails 插件),您可以比完整的脚本(如前面的 PHP 示例)更简单地完成此操作。

In your controller:在您的控制器中:

def index

 respond_to do |format|
   format.html # Your HTML view
   format.pdf { render :layout => false }
 end
end

The render :layout => false part tells the browser to open up the "Would you like to download this file?" render :layout => false 部分告诉浏览器打开“你想下载这个文件吗?” prompt instead of attempting to render the PDF.提示而不是尝试呈现 PDF。 Then you would be able to link to the file normally: http://mysite.com/myawesomepdf.pdf然后您就可以正常链接到该文件: http : //mysite.com/myawesomepdf.pdf

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM