Có thể lưu trang HTML dưới dạng PDF bằng JavaScript hoặc jquery không?


83

Có thể lưu trang HTML dưới dạng PDF bằng JavaScript hoặc jquery không?

Chi tiết:

Tôi đã tạo một Trang HTML có chứa một bảng. Nó có một nút 'lưu dưới dạng PDF'. Nếu người dùng nhấp vào nút đó thì trang HTML đó phải chuyển đổi thành tệp PDF.

Có thể sử dụng JavaScript hoặc jquery không?


3
Miễn là tôi biết, Javascript không thể tạo tài liệu pdf.
Khoa Le

1
Ngày nay, rất nhiều người có thể in ra PDF. Vì vậy, chức năng đó được cho là không cần thiết.
Eric

4
PDF là một ngôn ngữ dựa trên văn bản. Bạn sẽ khó tìm thấy ngôn ngữ lập trình mà bạn không thể tạo ra nó.
Quentin

1
câu trả lời có thể có ở đây: stackoverflow.com/questions/12108806/…
colin

Câu trả lời:


28

, Sử dụng jspdf Để tạo tệp pdf.

Sau đó, bạn có thể biến nó thành một URI dữ liệu và đưa liên kết tải xuống vào DOM

Tuy nhiên, bạn sẽ cần phải tự mình viết mã chuyển đổi HTML sang pdf.

Chỉ cần sử dụng các phiên bản thân thiện với máy in của trang của bạn và để người dùng chọn cách họ muốn in trang.

Chỉnh sửa: Rõ ràng nó có hỗ trợ tối thiểu

Vì vậy, câu trả lời là viết trình viết PDF của riêng bạn hoặc nhờ một trình viết PDF hiện có để làm điều đó cho bạn (trên máy chủ).


jspdf trông thú vị, nhưng các bản trình diễn không hoạt động trong Firefox 5.0 cũng như IE!
Tim Büthe

jspdf có hỗ trợ tối thiểu cho các tính năng, thậm chí không hỗ trợ đồ họa. Nhưng trừ khi có hệ thống phong cách và nội dung kết xuất - về cơ bản nó chỉ hữu ích cho các ghi chú nhỏ. Nếu không, bạn cũng sẽ phải viết toàn bộ trình kết xuất HTML bằng JS (hoặc ăn gian và sử dụng canvas với drawElement, thứ chỉ được hỗ trợ trong firefox mà tôi có vẻ nhớ). Javascript thực sự không phù hợp với dòng mã hóa này nếu bạn hỏi tôi. Có lẽ gọi một dịch vụ web bên ngoài là cách dễ nhất.
Jon Lennart Aasenden

JavaScript (như một ngôn ngữ) hoàn toàn phụ thuộc vào nó. JavaScript chạy với các hạn chế của các mô hình bảo mật trình duyệt và API ít hơn.
Quentin

4
Tôi chắc chắn rằng ai đó có thể xây một ngôi nhà từ que diêm hoặc tăm xỉa răng, nhưng vào cuối ngày - một trình biên dịch pdf hoàn chỉnh với hỗ trợ khâu, đồ họa, nhúng phông chữ, kiểu dáng và bảng tra cứu đầy đủ chức năng thì không còn nghi ngờ gì nữa. Hãy xem mã nguồn của jspdf - nó chỉ hỗ trợ các thẻ đơn giản nhất và không có từ điển tra cứu. Khó có thể thực hiện một trình biên dịch pdf hoàn chỉnh trong C ++ hoặc Delphi, thậm chí, việc triển khai JS thuần túy sẽ là hành động tự sát. Có những công ty làm việc trong nhiều năm chỉ bán các trình biên dịch pdf của họ (ví dụ: xem gnostice). Đây không phải là "một lớp lót".
Jon Lennart Aasenden

@JonLennartAasenden Có nó không có hỗ trợ tối thiểu. Bạn vẫn có thể viết trình viết PDF bằng js nếu bạn muốn. Tuy nhiên, nó không phải là một nhiệm vụ dễ dàng. Việc triển khai JS thuần túy cũng giống như C ++ hoặc Delphi. Đừng giả vờ JS là một công dân hạng hai.
Raynos

15

Ya nó rất dễ thực hiện với javascript. Hy vọng mã này hữu ích cho bạn.

Bạn sẽ cần thư viện 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>

liên kết jsfiddle đây


1
hình ảnh không in trong pdf :( bạn có một giải pháp ??
Maestro Vladimir

1
Nó không hỗ trợ các phép nhân cũng như kiểu css đúng cách.
Động

1
Không hỗ trợ bảng :( Loved cách tiếp cận
FutoRicky

3
Liên kết JSFiddle dẫn đến trang 404
Oscar Chambers


7

Bạn có thể sử dụng Phantomjs. Tải xuống tại đây và sử dụng ví dụ sau để kiểm tra tính năng chuyển đổi html-> pdf https://github.com/ariya/phantomjs/blob/master/examples/rasterize.js

Mã ví dụ:

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

Bạn có thể sử dụng nó với javascript thay vì tiện ích dòng lệnh không?
Động

@Dynamic không, đây là một trình duyệt không có đầu mà bạn có thể điều khiển thông qua javascript. Bạn có thể yêu cầu nó in một trang web sang PDF thông qua javascript nhưng cách triển khai không phải là javascript. Tuy nhiên, đã sử dụng nó cho trường hợp chính xác này bằng cách gói nó trong một ứng dụng sử dụng hàng đợi các trang để in và tôi sử dụng javascript để thêm các mục vào hàng đợi. Tương tự, bạn có thể gói nó trong một dịch vụ. Để kiểm soát cách điều được in dù bạn dưới giới hạn tương tự như chrome in (ví dụ như css và js để tạo ra một cái nhìn thân thiện in)
Shane

7

Tôi đã sử dụng jsPDFdom-to-imagethư viện để xuất HTML sang PDF.

Tôi đăng ở đây như là tham chiếu đến mối quan tâm của ai.

$('#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");
      });
});

Demo: https://jsfiddle.net/viethien/md03wb21/27/


Nếu tôi truy cập chế độ đáp ứng và tải xuống pdf, trang pdf không đến đúng cách, Có cách nào để đạt được kết quả tương tự như chế độ máy tính để bàn khi tôi tải xuống bằng chế độ đáp ứng không.
Nancy

6

Đây là cách tôi sẽ làm điều đó, một ý tưởng không phải là thiết kế chống đạn, bạn cần phải sửa đổi nó

  • Người dùng nhấp vào nút lưu dưới dạng PDF
  • Máy chủ được gửi một cuộc gọi bằng ajax
  • Máy chủ phản hồi bằng một URL cho PDF được tạo bằng HTML, tôi đã sử dụng Apache FOP rất thành công
  • Các js xử lý phản hồi ajax thực hiện một location.href để trỏ URL được gửi bởi JS và ngay khi URL đó tải, nó sẽ gửi tệp bằng cách sử dụng tiêu đề bố trí nội dung dưới dạng tệp đính kèm buộc người dùng phải tải tệp xuống.

2

Việc chuyển đổi html sang pdf phía máy chủ dễ dàng và đáng tin cậy hơn nhiều. Chúng tôi đang sử dụng Google Puppeteer. Nó được duy trì tốt với các trình bao bọc cho bất kỳ ngôn ngữ phía máy chủ nào mà bạn chọn. Puppeteer sử dụng Chrome không đầu để tạo ảnh chụp màn hình và / hoặc tệp PDF. Nó sẽ giúp bạn tiết kiệm được rất nhiều cơn đau đầu, đặc biệt nếu bạn cần tạo các tệp PDF phức tạp với các bảng, hình ảnh, đồ thị, nhiều trang, v.v.

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


2

Có một cách rất rõ ràng khác để chuyển đổi HTML sang PDf bằng JavaScript: sử dụng một API trực tuyến cho điều đó. Điều này sẽ hoạt động tốt nếu bạn không cần thực hiện chuyển đổi khi người dùng ngoại tuyến.

PdfMage là một trong những tùy chọn có API đẹp và cung cấp các tài khoản miễn phí. Tôi chắc rằng bạn có thể tìm thấy nhiều lựa chọn thay thế (ví dụ: tại đây )

Đối với API PdfMage, bạn sẽ có một cái gì đó như sau:

 $.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 dường như không thể lên được nữa
Zach Saucier

1
PDFMage không còn miễn phí, rất tiếc.
Prometheus

1

Đúng. Ví dụ: bạn có thể sử dụng giải pháp của https://grabz.it .

Nó có một API Javascript có thể được sử dụng theo nhiều cách khác nhau để lấy và điều khiển ảnh chụp màn hình. Để sử dụng nó trong ứng dụng của mình, trước tiên, bạn cần phải có khóa ứng dụng và bí mậttải xuống SDK Javascript miễn phí.

Vì vậy, hãy xem một ví dụ đơn giản để sử dụng nó:

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

Sau đó, bạn chỉ cần đợi một lúc và hình ảnh sẽ tự động xuất hiện ở cuối trang mà bạn không cần tải lại trang.

Đó là một trong những đơn giản nhất. Để biết thêm ví dụ về thao tác hình ảnh, hãy đính kèm ảnh chụp màn hình vào các phần tử và v.v. hãy kiểm tra tài liệu .


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>


Đoạn mã trên không hoạt động trong bất kỳ trình duyệt nào tôi đã thử nghiệm. Không có gì xảy ra khi bạn nhấp vào nút "Tải xuống Mã thông báo" và không có lỗi nào được ghi lại. Bạn có thể vui lòng kiểm tra.
Almeister 9

0

Tóm lại: không. Vấn đề đầu tiên là quyền truy cập vào hệ thống tệp, trong hầu hết các trình duyệt được đặt thành không theo mặc định vì lý do bảo mật. Các trình duyệt hiện đại đôi khi hỗ trợ lưu trữ tối thiểu dưới dạng cơ sở dữ liệu hoặc bạn có thể yêu cầu người dùng bật quyền truy cập tệp.

Nếu bạn có quyền truy cập vào hệ thống tệp thì việc lưu dưới dạng HTML không khó lắm (xem đối tượng tệp trong tài liệu JS) - nhưng PDF thì không dễ dàng như vậy. PDF là một định dạng tệp khá nâng cao thực sự không phù hợp với Javascript. Nó yêu cầu bạn viết thông tin trong các kiểu dữ liệu không được hỗ trợ trực tiếp bởi Javascript, chẳng hạn như các từ và quads. Bạn cũng cần xác định trước một hệ thống tra cứu từ điển phải được lưu vào tệp. Tôi chắc rằng ai đó có thể làm cho nó hoạt động, nhưng nỗ lực và thời gian liên quan sẽ tốt hơn dành cho việc học C ++ hoặc Delphi.

Tuy nhiên, có thể xuất HTML nếu người dùng cấp cho bạn quyền truy cập không hạn chế


2
Tại sao C ++ và Delphi kế thừa tốt hơn trong việc tạo trình soạn thảo PDF?
Raynos

2
Bởi vì những ngôn ngữ đó được xây dựng để tạo ra phần mềm tiên tiến. Javascript đã không. Javascript chưa bao giờ hoàn thiện, đây là lý do tại sao hệ thống nguyên mẫu bị treo. Tác giả đã lên kế hoạch thêm một HL vào nó với các lớp thực và nhiều kiểu dữ liệu hơn - nhưng anh ta không có thời gian. Vì vậy, nó đã được xuất bản "như là". Nó không hỗ trợ con trỏ, cấp phát bộ nhớ thô rất khó, nó không hỗ trợ một số kiểu dữ liệu gốc mà bạn tìm thấy trong các ngôn ngữ khác, nó không hỗ trợ cấu trúc đóng gói (struct trong C, Record trong Pascal) ... danh sách là vô tận. Tôi yêu JS, nhưng nó là một món đồ chơi của trình duyệt, không phải ngôn ngữ thực.
Jon Lennart Aasenden

Có một số người viết dựa trên Java ở đó, và nếu bạn nhìn vào kích thước của mã nguồn, có thể thấy khá rõ ràng rằng nó sẽ còn dài hơn dưới Javascript - nhưng điểm quan trọng là: định dạng IO và các bảng tra cứu . Tôi chắc rằng ai đó có thể làm được - nhưng nó sẽ cực kỳ chậm và về cơ bản, lãng phí thời gian. Và bạn sẽ nhúng dữ liệu phông chữ như thế nào? Bạn thậm chí không thể lấy tệp từ Hệ điều hành, chứ đừng nói đến việc chuyển đổi nó (bản thân nó là cả một thư viện) và nhúng nó. Tại sao phải xây một ngôi nhà bằng que diêm khi bạn chỉ có thể, xây một ngôi nhà bình thường?
Jon Lennart Aasenden

2
"nhưng nó là một đồ chơi trình duyệt, không phải là một ngôn ngữ thực." Điều đó giống như nói Scheme không phải là một ngôn ngữ thực. "hẳn là hiển nhiên rằng nó sẽ còn nằm dưới Javascrip", không. Java thì dài dòng hơn nhiều so với JavaScript. Nó sẽ ngắn hơn khoảng 2/3 so với phiên bản Java. "nhưng về cơ bản nó sẽ cực kỳ chậm," Cực kỳ chậm nghĩa là chậm hơn 3/4 lần so với C ++? Chúng tôi có thể làm ơn ngừng đối xử với js như một công dân hạng hai được không. Cảm ơn.
Raynos

11
Bất kể ý kiến ​​cá nhân của bạn, Jon, bạn có thể ngừng khẳng định rằng "Javascript không phải là một ngôn ngữ thực", bởi vì đó là BS. Javascript là một ngôn ngữ cực kỳ mạnh mẽ được tối ưu hóa cho các mục đích khác với ngôn ngữ biên dịch cấp thấp như C hoặc C ++. Có những điều bạn có thể làm trong JS mà bạn không thể làm trong C hoặc C ++, nhưng điều đó có nghĩa là C và C ++ không phải là ngôn ngữ "thực"? Không, chỉ là chúng dành cho những thứ khác nhau. JS thực sự là một ngôn ngữ lập trình như bất kỳ ngôn ngữ hoàn chỉnh nào khác.
Isochronous
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.