使用JavaScript将HTML页面中的一个div下载为PDF

117

我有一个id为"content"的内容

,其中包含一些图表和表格。当用户点击下载按钮时,我想将该
作为pdf下载。是否可以使用JavaScript或jQuery来实现这一点?


1
http://code.google.com/p/jspdf/ 是我所知道的最好的能够实现这个功能的库。 - alvinarul
我该如何使用jsPDF从特定的div中下载内容?从他们网站上的示例来看,似乎无法实现此功能。 - Midhun Mathew
5个回答

131

您可以使用jsPDF来完成此操作。

<div id="content">
     <h3>Hello, this is a H3 tag</h3>

    <p>A paragraph</p>
</div>
<div id="editor"></div>
<button id="cmd">generate PDF</button>

JavaScript:

var doc = new jsPDF();
var specialElementHandlers = {
    '#editor': function (element, renderer) {
        return true;
    }
};

$('#cmd').click(function () {
    doc.fromHTML($('#content').html(), 15, 15, {
        'width': 170,
            'elementHandlers': specialElementHandlers
    });
    doc.save('sample-file.pdf');
});

31
我这里有一个问题。我在这里添加的CSS在PDF文件中没有生效。而且我还有一些图表,它们也没有出现在PDF中。我该怎么做才能让它们出现呢? - Midhun Mathew
18
jsPDF不能有效地格式化表格,它只把td/th解释为display:block;。 - Dave
3
使用以上代码,我们只能创建一次 PDF 文件。但是第二次不起作用。为了使它正常工作,请查看 @kristof-feys 的 答案,我们需要在 click 函数内部声明 doc 变量。 - Mahendran Sakkarai
5
很不错,只是可惜CSS没有呈现出来 :/ - Nicholas
2
我花了很多时间使用jsPDF工作,最终发现它无法呈现CSS。我的表格看起来很糟糕,无法正确添加任何图像。jsPDF一无是处。 - Agent K
显示剩余15条评论

57

在一个<div class='html-content'>....</div>中的内容可以使用jspdfhtml2canvas以样式下载为pdf。

你需要引用这两个js库,

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
<script type="text/javascript" src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>

然后调用下面的函数:

//Create PDf from HTML...
function CreatePDFfromHTML() {
    var HTML_Width = $(".html-content").width();
    var HTML_Height = $(".html-content").height();
    var top_left_margin = 15;
    var PDF_Width = HTML_Width + (top_left_margin * 2);
    var PDF_Height = (PDF_Width * 1.5) + (top_left_margin * 2);
    var canvas_image_width = HTML_Width;
    var canvas_image_height = HTML_Height;

    var totalPDFPages = Math.ceil(HTML_Height / PDF_Height) - 1;

    html2canvas($(".html-content")[0]).then(function (canvas) {
        var imgData = canvas.toDataURL("image/jpeg", 1.0);
        var pdf = new jsPDF('p', 'pt', [PDF_Width, PDF_Height]);
        pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin, canvas_image_width, canvas_image_height);
        for (var i = 1; i <= totalPDFPages; i++) { 
            pdf.addPage(PDF_Width, PDF_Height);
            pdf.addImage(imgData, 'JPG', top_left_margin, -(PDF_Height*i)+(top_left_margin*4),canvas_image_width,canvas_image_height);
        }
        pdf.save("Your_PDF_Name.pdf");
        $(".html-content").hide();
    });
}

参考: 从HTML画布和jspdf生成多页PDF.

也许这会帮助某人。


9
这对我非常有帮助,谢谢。它可以保留所有的样式,但是它确实有一些限制(将PDF创建为图像,因此无法搜索;似乎也稍微有点模糊)。 - jramm
如何设置页面断点,如果一半的内容无法适应一页? - SHEKHAR SHETE
1
对我来说工作得非常好。 唯一的问题是我的一些SVG图标没有渲染! - Felipe N Moura
1
太棒了!这对我非常有效。在我的情况下,我只需要导出一个包含几个表格和图形的 div。非常感谢! - Andrew

4
您的解决方案需要使用一些 ajax 方法将 html 传递到具有 html 到 pdf 转换功能的后端服务器,然后将生成的 pdf 输出返回给浏览器。
首先设置客户端代码,我们将设置 jquery 代码如下:
   var options = {
            "url": "/pdf/generate/convert_to_pdf.php",
            "data": "data=" + $("#content").html(),
            "type": "post",
        }
   $.ajax(options)

然后拦截来自html2pdf生成脚本的数据(可能来源于互联网)。
convert_to_pdf.php(在JQUERY代码中作为url给出)看起来像这样 -

<?php
    $html = $_POST['data'];
    $pdf = html2pdf($html);
    
    header("Content-Type: application/pdf"); //check this is the proper header for pdf
    header("Content-Disposition: attachment; filename='some.pdf';");
    echo $pdf;
?>

你说的“具有HTML转PDF功能”是什么意思? - Midhun Mathew
可以引用相同的URL吗,还是应该更改它? - Midhun Mathew
你需要一个稍微不同的URL,这样你才能区分这两个内容。 - DevZer0
那个URL应该是什么样子的?你能给一个例子吗? - Midhun Mathew
2
如果CSS通过链接的方式引用,你就会遇到麻烦,因为后端程序将不知道如何找到样式,除非它可以获取CSS文件并从文件中应用样式。 - TheRealChx101
此解决方案不考虑应用于HTML的任何样式规则。 - Dario Corbelli

3

据我所知,没有原生的jQuery函数可以做到这一点。最好的选择是在服务器上处理转换。如何处理取决于您使用的语言(.net、php等)。您可以将div的内容传递给处理转换的函数,该函数将返回一个pdf文件给用户。


亲爱的朋友,注意问题...使用JavaScript将HTML页面中的div下载为PDF。 - R.Akhlaghi

0

是的,可以使用JS捕获div作为PDF。您可以检查https://grabz.it提供的解决方案。他们有漂亮干净的JavaScript API,允许您捕获单个HTML元素(如div或span)的内容。

因此,您需要一个app+key和免费的SDK来使用它。使用方法如下:

假设您有一个HTML:

<div id="features">
    <h4>Acme Camera</h4>
    <label>Price</label>$399<br />
    <label>Rating</label>4.5 out of 5
</div>
<p>Cras ut velit sed purus porttitor aliquam. Nulla tristique magna ac libero tempor, ac vestibulum felisvulput ate. Nam ut velit eget
risus porttitor tristique at ac diam. Sed nisi risus, rutrum a metus suscipit, euismod tristique nulla. Etiam venenatis rutrum risus at
blandit. In hac habitasse platea dictumst. Suspendisse potenti. Phasellus eget vehicula felis.</p>

要捕获特征 ID 下方的内容,您需要执行以下操作:

//add the sdk
<script type="text/javascript" src="grabzit.min.js"></script>
<script type="text/javascript">
//login with your key and secret. 
GrabzIt("KEY", "SECRET").ConvertURL("http://www.example.com/my-page.html",
{"target": "#features", "format": "pdf"}).Create();
</script>

你需要将http://www.example.com/my-page.html替换成你的目标URL,并根据你的CSS选择器替换#feature

就这些。现在,当页面加载时,图像屏幕截图将在与脚本标签相同的位置创建,其中包含所有特征div的内容,而没有其他内容。

还有其他配置和自定义您可以对div-screenshot机制进行,请查看此处


4
我认为你只能免费使用Grabz.it进行1,000次截屏和100次"抓取"。所以,除非你愿意付费,否则这不是一种永久性的解决方案。 - BrettC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接