HTML sayfasını JavaScript veya jquery kullanarak PDF olarak kaydetmek mümkün müdür?


84

HTML sayfasını JavaScript veya jquery kullanarak PDF olarak kaydetmek mümkün müdür?

Detayda:

Bir tablo içeren bir HTML Sayfası oluşturdum. Tek bir düğme 'PDF olarak kaydet' vardır. Kullanıcı bu düğmeyi tıklarsa, o HTML sayfasının PDF dosyası olarak dönüştürülmesi gerekir.

JavaScript veya jquery kullanarak mümkün mü?


3
Bildiğim kadarıyla Javascript pdf dokümanları oluşturamaz.
Khoa Le

1
Bugünlerde birçok kişi PDF'lere yazdırabilir. Dolayısıyla bu işlevsellik tartışmasız gerekli değildir.
Eric

4
PDF, metin tabanlı bir dildir. Onu üretemeyeceğiniz bir programlama dili bulmakta zorlanacaksınız.
Quentin

Yanıtlar:


28

Evet , pdf dosyası oluşturmak için jspdf kullanın .

Daha sonra bunu bir veri URI'sına dönüştürebilir ve DOM'a bir indirme bağlantısı enjekte edebilirsiniz.

Bununla birlikte, HTML'den pdf'ye dönüştürmeyi kendiniz yazmanız gerekecektir.

Sayfanızın yazıcı dostu sürümlerini kullanın ve kullanıcının sayfayı nasıl yazdırmak istediğini seçmesine izin verin.

Düzenleme: Görünüşe göre minimum desteğe sahip

Yani cevap, kendi PDF yazıcınızı yazmak veya sizin için (sunucuda) yapması için mevcut bir PDF yazıcısını almaktır.


jspdf ilginç görünüyor, ancak demolar Firefox 5.0 veya IE'de çalışmıyor!
Tim Büthe

jspdf, özellikler için minimum desteğe sahiptir, grafikleri bile desteklemez. Ancak stil sistemi ve oluşturma öğeleri orada olmadığı sürece - temelde yalnızca küçük notlar için kullanışlıdır. Aksi takdirde, JS'de de tam bir HTML oluşturucu yazmanız gerekir (veya hile yapıp, sadece firefox'ta desteklenen drawElement ile tuvali kullanmanız ve hatırladığım kadarıyla). Bana sorarsanız, Javascript gerçekten bu kodlama hattına uygun değil. Belki de harici bir web servisini aramak en kolay yoldur.
Jon Lennart Aasenden

JavaScript (dil olarak) tamamen buna bağlıdır. JavaScript, tarayıcı güvenlik modellerinin ve API'lerin kısıtlamaları ile daha az çalışır.
Quentin

4
Eminim ki birileri kibritlerden veya kürdanlardan bir ev inşa edebilir, ancak günün sonunda - dikiş, grafikler, yazı tipi yerleştirme, stiller ve tamamen işlevsel arama tablolarını destekleyen tamamen gelişmiş bir pdf derleyicisi söz konusu değil. Jspdf için kaynağa bir göz atın - yalnızca en basit etiketleri destekler ve arama sözlüğü içermez. Tamamen gelişmiş bir pdf derleyicisini C ++ veya Delphi'de yapmak zordur, hatta saf bir JS uygulaması intihara meyillidir. Yıllarca sadece kendi pdf derleyicilerini satarak çalışan şirketler var (örneğin gnostice'e bakınız). Bu bir "tek astar" değildir.
Jon Lennart Aasenden

@JonLennartAasenden Evet, minimum desteğe sahip. Yine de isterseniz js'de bir PDF yazıcısı yazabilirsiniz. Ancak bu kolay bir iş değil. Saf bir JS uygulaması, C ++ veya Delphi kadar intihara meyillidir. JS'nin ikinci sınıf bir vatandaş olduğunu düşünmeyin.
Raynos

15

Javascript ile yapmak çok kolay. Umarım bu kod sizin için yararlıdır.

JSpdf kitaplığına ihtiyacınız olacak .

<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 buraya bağlantı


1
resim pdf olarak basılmıyor :( bir çözümünüz var mı ??
Maestro Vladimir

2
Çoklu sayfaları veya css stillerini doğru şekilde desteklemiyor.
Dynamic

1
Tabloları desteklemiyor :( Yaklaşımı
beğendim

3
JSFiddle bağlantısı bir 404 sayfasına yönlendiriyor
Oscar Chambers


7

Phantomj'leri kullanabilirsiniz. Buradan indirin ve html-> pdf dönüştürme özelliğini test etmek için aşağıdaki örneği kullanın https://github.com/ariya/phantomjs/blob/master/examples/rasterize.js

Örnek kod:

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

Komut satırı yardımcı programı yerine javascript ile kullanabilir misiniz?
Dynamic

@Dinamik hayır, bu javascript ile kontrol edebileceğiniz başsız bir tarayıcıdır. JavaScript aracılığıyla bir web sayfasını PDF olarak yazdırmasını söyleyebilirsiniz, ancak uygulama javascript değildir. Ancak, yazdırmak için bir sayfa kuyruğu kullanan bir uygulamaya sararak tam bu senaryo için kullandım ve kuyruğa girişler eklemek için javascript kullanıyorum. Benzer şekilde bir servise de sarabilirsiniz. Krom baskı ile aynı sınırlama altında olmanıza rağmen nesnelerin nasıl yazdırılacağını kontrol etmek için (örneğin, yazdırmaya uygun bir görünüm oluşturmak için css ve js)
Shane

7

HTML'yi PDF'ye dışa aktarmak için jsPDFve dom-to-imagekitaplık kullandım .

Burada kimin endişesine referans olarak gönderiyorum.

$('#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/


Duyarlı moda gidip pdf dosyasını indirirsem, pdf sayfası düzgün gelmiyor, Duyarlı modu kullanarak indirdiğimde masaüstü moduyla aynı sonucu elde etmenin bir yolu var mı?
Nancy

6

İşte bunu nasıl yapacağım, kurşun geçirmez tasarım değil bir fikir, onu değiştirmeniz gerekiyor

  • Kullanıcı PDF olarak kaydet düğmesini tıklar
  • Sunucuya ajax kullanılarak bir çağrı gönderilir
  • Sunucu HTML kullanılarak oluşturulan PDF için bir URL ile yanıt veriyor, Apache FOP'yi çok başarılı bir şekilde kullandım
  • Ajax yanıtını işleyen js, JS tarafından gönderilen URL'yi işaret etmek için bir location.href yapar ve bu URL yüklenir yüklenmez, kullanıcıyı dosyayı indirmeye zorlayan ek olarak içerik kullanım başlığını kullanarak dosyayı gönderir.

2

Html'yi pdf sunucu tarafına dönüştürmek çok daha kolay ve güvenilirdir. Google Puppeteer kullanıyoruz. Seçtiğiniz herhangi bir sunucu tarafı dili için sarmalayıcılarla iyi korunur. Puppeteer, ekran görüntüleri ve / veya PDF dosyaları oluşturmak için başsız Chrome kullanıyor. Özellikle tablolar, resimler, grafikler, birden çok sayfa vb. İçeren karmaşık PDF dosyaları oluşturmanız gerekiyorsa, sizi ÇOK baş ağrısından kurtaracaktır.

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


2

JavaScript kullanarak HTML'yi PDf'ye dönüştürmenin çok açık bir yolu daha var: bunun için çevrimiçi bir API kullanın. Kullanıcı çevrimdışıyken dönüşümü yapmanız gerekmiyorsa bu iyi çalışacaktır.

PdfMage , güzel bir API'ye sahip ve ücretsiz hesaplar sunan bir seçenektir. Eminim birçok alternatif bulabilirsin (örneğin, burada )

PdfMage API için şuna benzer bir şeye sahip olursunuz:

 $.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 artık ayakta görünmüyor
Zach Saucier

1
PDFMage maalesef artık ücretsiz değil.
Prometheus

1

Evet. Örneğin çözümü https://grabz.it ile kullanabilirsiniz .

Ekran görüntüsünü almak ve değiştirmek için farklı şekillerde kullanılabilen bir Javascript API'ye sahiptir. Bunu uygulamanızda kullanmak için önce bir uygulama anahtarı ve sırrı almanız ve ücretsiz Javascript SDK'yı indirmeniz gerekir.

Öyleyse, onu kullanmak için basit bir örnek görelim:

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

Daha sonra kısa bir süre bekleyin ve görüntü, sayfayı yeniden yüklemenize gerek kalmadan otomatik olarak sayfanın altında görünecektir.

Bu en basit olanıdır. Görüntü işleme, öğelere ekran görüntüsü ekleme vb . İle ilgili daha fazla örnek için belgelere bakın .


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>


Yukarıdaki kod, test ettiğim hiçbir tarayıcıda çalışmıyor. "Belirteç İndir" düğmesini tıkladığınızda hiçbir şey olmuyor ve hiçbir hata günlüğe kaydedilmiyor. Lütfen kontrol edebilir misin.
Almeister

0

Kısaca: hayır. İlk sorun, çoğu tarayıcıda güvenlik nedenleriyle varsayılan olarak hayır olarak ayarlanan dosya sistemine erişimdir. Modern tarayıcılar bazen bir veritabanı biçiminde minimalist depolamayı destekler veya kullanıcıdan dosya erişimini etkinleştirmesini isteyebilirsiniz.

Dosya sistemine erişiminiz varsa HTML olarak kaydetmek o kadar zor değildir (JS belgelerindeki dosya nesnesine bakın) - ancak PDF o kadar kolay değildir. PDF, Javascript için gerçekten uygun olmayan oldukça gelişmiş bir dosya formatıdır. Kelime ve dörtlü gibi Javascript tarafından doğrudan desteklenmeyen veri türlerinde bilgi yazmanızı gerektirir. Ayrıca, dosyaya kaydedilmesi gereken bir sözlük arama sistemini önceden tanımlamanız gerekir. Eminim birileri bunu çalıştırabilirdi, ancak harcanan çaba ve zaman C ++ veya Delphi öğrenmek için daha iyi harcanırdı.

Ancak, kullanıcı size kısıtlanmamış erişim verirse HTML dışa aktarımı mümkün olmalıdır


2
C ++ ve Delphi , bir PDF yazıcı oluşturmada kalıtımsal olarak neden daha iyidir?
Raynos

2
Çünkü bu diller, gelişmiş yazılımlar yapmak için oluşturuldu. Javascript değildi. Javascript asla bitmedi, bu yüzden prototip sistemi takılıyor. Yazar, ona gerçek sınıflar ve daha fazla veri türü içeren bir HL eklemeyi planlamıştı, ancak zamanı yoktu. Yani "olduğu gibi" yayınlandı. İşaretçileri desteklemez, ham bellek tahsisi ağrılıdır, diğer dillerde bulduğunuz bazı yerel veri türlerini desteklemez, paketlenmiş yapıları desteklemez (C'de yapı, Pascal'da Kayıt) ... liste sonsuzdur. JS'yi seviyorum ama bu bir tarayıcı oyuncağı, gerçek bir dil değil.
Jon Lennart Aasenden

Orada bazı Java tabanlı yazarlar var ve kaynak kodun boyutuna bakarsanız, Javascript altında daha uzun olacağı oldukça açık olmalıdır - ancak önemli nokta: IO biçimlendirme ve arama tabloları . Eminim birisi yapabilirdi - ama bu son derece yavaş ve temelde zaman kaybı olurdu. Ve yazı tipi verilerini nasıl katıştıracaksınız? Dosyayı işletim sisteminden bile alamazsınız, onu dönüştürebilir (ki bu başlı başına bir kitaplıktır) ve gömebilirsiniz. Normal bir ev inşa edebildiğiniz halde neden bir kibrit evi inşa edesiniz?
Jon Lennart Aasenden

2
"ama bu bir tarayıcı oyuncağı, gerçek bir dil değil." Bu, Scheme'nin gerçek bir dil olmadığını söylemek gibi. "Javascrip altında daha uzun süre olacağı oldukça açık olmalı", hayır. Java, JavaScript'ten çok daha ayrıntılıdır. Java sürümünden yaklaşık 2/3 daha kısa olmalıdır. "ama son derece yavaş ve temelde," Aşırı yavaş derken C ++ 'dan 3 / 4x daha yavaş mı demek istiyorsunuz? Lütfen js'ye ikinci sınıf vatandaş muamelesi yapmayı bırakabilir miyiz? Teşekkürler.
Raynos

11
Kişisel görüşünüz ne olursa olsun, Jon, "Javascript gerçek bir dil değil" iddiasını bırakabilir misin, çünkü bu BS. Javascript, C veya C ++ gibi düşük seviyeli derlenmiş bir dilden farklı amaçlar için optimize edilmiş son derece güçlü bir dildir. JS'de yapabileceğiniz, C veya C ++ 'da yapamayacağınız şeyler var, ancak bu C ve C ++' nın "gerçek" diller olmadığı anlamına mı geliyor? Hayır, sadece farklı şeyler içindir. JS, diğer turing-complete dilleri gibi gerçek bir programlama dilidir.
Eşzamanlı
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.