是否可以使用JavaScript或jquery将HTML页面另存为PDF?


83

是否可以使用JavaScript或jquery将HTML页面另存为PDF?

详细:

我生成了一个包含表的HTML页面。它有一个按钮“另存为PDF”。如果用户单击该按钮,则该HTML页面必须转换为PDF文件。

是否可以使用JavaScript或jquery?


3
据我所知,JavaScript无法创建pdf文档。
Khoa Le

1
如今,许多人都可以打印为PDF。因此可以说该功能不是必需的。
艾瑞克(Eric)

4
PDF是一种基于文本的语言。您将很难找到无法从中生成语言的编程语言。
昆汀

Answers:


28

是的,请使用jspdf创建pdf文件。

然后,您可以将其转换为数据URI,并将下载链接插入DOM

但是,您需要自己编写HTML到pdf的转换。

只需使用页面的打印机友好版本,然后让用户选择他要如何打印页面即可。

编辑:显然,它具有最小的支持

因此,答案是编写您自己的PDF编写器或让一个现有的PDF编写器为您(在服务器上)做。


jspdf看起来很有趣,但是演示无法在Firefox 5.0和IE中运行!
蒂姆·布斯(TimBüthe)2011年

jspdf对功能的支持最少,甚至不支持图形。但是除非有样式系统和渲染内容,否则它基本上只对小笔记有用。否则,您还必须在JS中编写一个完整的HTML渲染器(或者作弊并使用canvas和drawElement,我似乎还记得在firefox中才支持它)。如果您问我,JavaScript确实不适合这一行编码。也许调用外部Web服务是最简单的方法。
2011年

JavaScript(作为一种语言)完全可以使用它。运行受浏览器安全模型和API限制的JavaScript较少。
昆汀

4
我确定有人可以用火柴或牙签盖房子,但归根结底,完全支持针脚,图形,字体嵌入,样式和功能齐全的查找表的功能强大的pdf编译器是不可能的。看看jspdf的源代码-它仅支持最简单的标签,不支持查找字典。甚至在C ++或Delphi中都很难实现完全成熟的pdf编译器,即使纯JS实现也可能会自杀。有些公司工作多年,仅销售其pdf编译器(例如,请参阅gnostice)。这不是“一个班轮”。
乔恩·伦纳特·阿森登2011年

@JonLennartAasenden是的,它的支持很少。如果愿意,您仍然可以用js编写PDF编写器。但是,这不是一件容易的事。纯粹的JS实现与C ++或Delphi一样具有自杀性。不要假装JS是二等公民。
雷诺斯

15

是的,使用javascript非常容易。希望这段代码对您有用。

您将需要JSpdf库

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

    <p>a pararaph</p>
</div>
<div id="editor"></div>
<button id="cmd">Generate PDF</button>

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

    // This code is collected but useful, click below to jsfiddle link.
</script>

jsfiddle链接在这里


1
图片无法以pdf格式打印:(您有解决方案??
Ves大师

1
它不支持多页或CSS样式。
动态

1
不支持表格:(喜欢的方法
FutoRicky

3
该链接的jsfiddle导致404页
奥斯卡钱伯斯


7

您可以使用Phantomjs。在此处下载并使用以下示例测试html-> pdf转换功能https://github.com/ariya/phantomjs/blob/master/examples/rasterize.js

示例代码:

phantomjs.exe examples/rasterize.js http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/xhtml/index.html sample.pdf

您可以将其与javascript一起使用,而不是与命令行实用程序一起使用吗?
动态

@Dynamic不,这是您可以通过JavaScript控制的无头浏览器。您可以告诉它通过javascript将网页打印为PDF,但是实现不是javascript。但是,通过将其包装在一个消耗要打印的页面队列的应用程序中,将其用于此确切方案,并且我使用javascript将条目添加到队列中。同样,您可以将其包装在服务中。为了控制事物的打印方式,尽管您处于与chrome打印相同的限制下(例如,使用css和js创建友好的打印视图)
Shane

7

我使用jsPDFdom-to-image库将HTML导出为PDF。

我在这里发布有关谁关注的参考。

$('#downloadPDF').click(function () {
    domtoimage.toPng(document.getElementById('content2'))
      .then(function (blob) {
          var pdf = new jsPDF('l', 'pt', [$('#content2').width(), $('#content2').height()]);
          pdf.addImage(blob, 'PNG', 0, 0, $('#content2').width(), $('#content2').height());
          pdf.save("test.pdf");
      });
});

演示:https : //jsfiddle.net/viethien/md03wb21/27/


如果我进入响应模式并下载pdf,则pdf页面无法正常显示,当我使用响应模式下载时,有没有办法达到与桌面模式相同的结果。
南希

6

这是我的操作方式,它不是防弹设计,您需要对其进行修改

  • 用户单击另存为PDF按钮
  • 使用ajax向服务器发送呼叫
  • 服务器响应一个使用HTML生成的PDF的URL,我非常成功地使用了Apache FOP
  • 处理ajax响应的js执行一次location.href来指向JS发送的URL,并在URL加载后立即使用内容处置标头作为附件发送文件,从而迫使用户下载文件。

2

将html转换为pdf服务器端更加容易和可靠。我们正在使用Google Puppeteer。它可以通过包装程序很好地维护您选择的任何服务器端语言。Puppeteer使用无头Chrome浏览器来生成屏幕截图和/或PDF文件。这将为您省去很多麻烦,尤其是当您需要生成包含表格,图像,图形,多页等的复杂PDF文件时

https://developers.google.com/web/tools/puppeteer/


2

使用JavaScript将HTML转换为PDf的另一种非常明显的方法是:使用在线API。如果用户离线时不需要进行转换,则此方法会很好用。

PdfMage是一种具有不错的API并提供免费帐户的选项。我相信您可以找到许多替代方法(例如,这里

对于PdfMage API,您将具有以下内容:

 $.ajax({
    url: "https://pdfmage.org/pdf-api/v1/process",
    type: "POST",
    crossDomain: true,
    data: { Html:"<html><body>Hi there!</body></html>" },
    dataType: "json",
    headers: {
        "X-Api-Key": "your-key-here" // not very secure, but a valid option for non-public domains/intranet
    },
    success: function (response) {
        window.location = response.Data.DownloadUrl;
    },
    error: function (xhr, status) {
        alert("error");
    }
});

3
Freehtmltopdf.com似乎并不待涨下去
扎克索西耶

1
不幸的是,PDFMage不再免费。
普罗米修斯

1

是。例如,您可以通过https://grabz.it使用该解决方案。

它有一个Javascript API,可通过多种方式来抓取和操作屏幕截图。为了在您的应用程序中使用它,您需要首先获取一个应用程序密钥和机密,然后下载免费的Javascript SDK。

因此,让我们来看一个使用它的简单示例:

//first include the grabzit.min.js library in the web page
<script src="grabzit.min.js"></script>
//include the code below to add the screenshot to the body tag    
<script>
//use secret key to sign in. replace the url.
GrabzIt("Sign in to view your Application Key").ConvertURL("http://www.google.com").Create();
</script>

然后,稍等片刻,图像将自动出现在页面底部,而无需重新加载页面。

那是最简单的。有关图像处理,将屏幕快照附加到元素等的更多示例,请参阅文档


1

$('#cmd2').click(function() {
  	var options = {
		//'width': 800,
  	};
  	var pdf = new jsPDF('p', 'pt', 'a4');
  	pdf.addHTML($("#content2"), -1, 220, options, function() {
    	pdf.save('admit_card.pdf');
  	});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js"></script>

<div id="content2" style="background: #fff;border-bottom: 1px solid #ffffff;">
                    	<div class="tokenDet" style="padding: 15px;border: 1px solid #000;width: 80%;margin: 0 auto;position: relative;overflow: hidden;">
                        	<div class="title" style="text-align: center;border-bottom: 1px solid #000;margin-bottom: 15px;">
                            	<h2>Entrance Exam Hall Ticket</h2>
                            </div>
                            <div class="parentdiv" style="display: inline-block;width: 100%;position: relative;">
                            	<div class="innerdiv" style="width: 80%;float: left;">
                            		<div class="restDet">
                                        <div class="div">
                                            <div class="label" style="width: 30%;float: left;">
                                                <strong>Name</strong>
                                            </div>
                                            <div class="data" style="width: 70%;display: inline-block;">
                                                <span>Santanu Patra</span>
                                            </div>
                                            <div class="label" style="width: 30%;float: left;">
                                                <strong>D.O.B.</strong>
                                            </div>
                                            <div class="data" style="width: 70%;display: inline-block;">
                                                <span>17th April, 1995</span>
                                            </div>
                                            <div class="label" style="width: 30%;float: left;">
                                                <strong>Address</strong>
                                            </div>
                                            <div class="data" style="width: 70%;display: inline-block;">
                                                <span>P.S. Srijan Corporate Park, Saltlake, Sector 5, Kolkata-91</span>
                                            </div>
                                            <div class="label" style="width: 30%;float: left;">
                                                <strong>Contact Number</strong>
                                            </div>
                                            <div class="data" style="width: 70%;display: inline-block;">
                                                <span>9874563210</span>
                                            </div>
                                            <div class="label" style="width: 30%;float: left;">
                                                <strong>Email Id</strong>
                                            </div>
                                            <div class="data" style="width: 70%;display: inline-block;">
                                                <span>santanu@macallied.com</span>
                                            </div>
                                            <div class="label" style="width: 30%;float: left;">
                                                <strong>Parent(s) Name</strong>
                                            </div>
                                            <div class="data" style="width: 70%;display: inline-block;">
                                                <span>S. Patra</span><br /><span>7896541230</span>
                                            </div>
                                            <div class="label" style="width: 30%;float: left;">
                                                <strong>Exam Center</strong>
                                            </div>
                                            <div class="data" style="width: 70%;display: inline-block;">
                                                <span>Institute of Engineering & Management</span>
                                            </div>
                                            <div class="label" style="width: 30%;float: left;">
                                                <strong>Hall Number</strong>
                                            </div>
                                            <div class="data" style="width: 70%;display: inline-block;">
                                                <span>COM-32</span>
                                            </div>
                                        </div>
                                    </div>
                            	</div>
                                <div class="sideDiv" style="width: 20%;float: left;">
                                	<div class="atts" style="float: left;width: 100%;">
                                    	<div class="photo" style="width: 115px;height: 150px;float: right;">
                                        	<img src="images/candidateImg.gif" style="width: 100%;"/>
                                        </div>
                                        <div class="sign" style="position: absolute;bottom: 0;right: 0;border-top: 1px dashed #000;left: 80%;text-align: right;">
                                        	<small>Self Attested</small>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <button class="btn btn-info" id="cmd2">Download Token</button>


上面的代码不适用于我测试过的任何浏览器。当您单击“下载令牌”按钮并且没有错误记录时,什么也没有发生。你能检查一下吗?
Almeister9 '18

0

简而言之:不。第一个问题是对文件系统的访问,由于安全原因,在大多数浏览器中默认将其设置为no。现代浏览器有时以数据库形式支持简约存储,或者您可以要求用户启用文件访问。

如果您有权访问文件系统,那么将其另存为HTML并不是那么困难(请参阅JS文档中的文件对象)-但是PDF并不是那么容易。PDF是一种非常高级的文件格式,确实不适合Javascript。它要求您以Javascript不直接支持的数据类型(例如单词和四边形)编写信息。您还需要预定义必须保存到文件中的字典查找系统。我确信有人可以使其工作,但是花更多的精力和时间来学习C ++或Delphi会更好。

但是,如果用户为您提供非受限访问,则应该可以进行HTML导出


2
为什么C ++和Delphi在继承方面更擅长创建PDF编写器?
雷诺斯

2
因为这些语言是为制造高级软件而构建的。JavaScript不是。Javascript从未完成,这就是原型系统被淘汰的原因。作者曾计划为HL添加真实的类和更多的数据类型-但他没有时间。因此它按“原样”出版。它不支持指针,原始内存分配很痛苦,不支持您在其他语言中找到的某些本机数据类型,不支持打包结构(C中的结构,Pascal中的Record)……列表是无止境的。我喜欢JS,但这是浏览器的玩具,不是真正的语言。
乔恩·伦纳特·阿森登2011年

那里有一些基于Java的编写器,如果您查看源代码的大小,应该很明显地证明在Javascript下它的长度甚至更长-但关键是:IO格式和查找表。我敢肯定有人会做到这一点-但那将非常缓慢,而且基本上是在浪费时间。以及如何嵌入字体数据?您甚至无法从OS中获取文件,更不用说对其进行转换(它本身是一个完整的库)并进行嵌入。当您可以建造普通房屋时,为什么还要盖火柴房?
乔恩·伦纳特·阿森登2011年

2
“但这是浏览器的玩具,不是真实的语言。” 这就像说Scheme不是一种真正的语言。“应该相当不言自明,在Javascrip下它甚至更长一些”,没有。Java比JavaScript更冗长。它应该比Java版本短约2/3。“但是基本上会非常慢。”“非常慢”是指比C ++慢3/4倍?我们能否停止将js视为二等公民。谢谢。
雷诺斯

11
无论您的个人意见如何,Jon都可以停止断言“ Javascript不是真正的语言”,因为那是BS。Javascript是一种非常强大的语言,与C或C ++这样的低级编译语言相比,它针对不同的目的进行了优化。在JS中可以执行某些操作,而在C或C ++中则无法执行这些操作,但这是否意味着C和C ++不是“真正的”语言?不,只是它们的意思是不同的东西。JS与任何其他图灵完备的语言一样,都是真正的编程语言。
2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.