Ist es möglich, HTML-Seiten mit JavaScript oder jquery als PDF zu speichern?

83

Ist es möglich, HTML-Seiten mit JavaScript oder jquery als PDF zu speichern?

Im Detail:

Ich habe eine HTML-Seite generiert, die eine Tabelle enthält. Es hat eine Schaltfläche "Als PDF speichern". Wenn der Benutzer auf diese Schaltfläche klickt, muss diese HTML-Seite als PDF-Datei konvertiert werden.

Ist es möglich mit JavaScript oder jquery?

RAM
quelle
3
Solange ich weiß, kann Javascript keine PDF-Dokumente erstellen.
Khoa Le
1
Viele Leute können heutzutage in PDFs drucken. Diese Funktionalität ist also wohl nicht erforderlich.
Eric
4
PDF ist eine textbasierte Sprache. Es fällt Ihnen schwer, eine Programmiersprache zu finden, aus der Sie sie nicht generieren können.
Quentin
1
mögliche Antwort hier: stackoverflow.com/questions/12108806/...
colin

Antworten:

28

Ja , jspdf verwenden, um eine PDF-Datei zu erstellen.

Sie können es dann in einen Daten-URI umwandeln und einen Download-Link in das DOM einfügen

Sie müssen jedoch die Konvertierung von HTML in PDF selbst schreiben.

Verwenden Sie einfach druckerfreundliche Versionen Ihrer Seite und lassen Sie den Benutzer auswählen, wie er die Seite drucken möchte.

Edit: Anscheinend hat es nur minimale Unterstützung

Die Antwort lautet also, schreiben Sie Ihren eigenen PDF-Writer oder lassen Sie einen vorhandenen PDF-Writer dies für Sie erledigen (auf dem Server).

Raynos
quelle
jspdf sieht interessant aus, aber die Demos funktionieren weder in Firefox 5.0 noch im IE!
Tim Büthe
jspdf bietet nur minimale Unterstützung für Funktionen, es werden nicht einmal Grafiken unterstützt. Aber wenn das Stilsystem und das Rendering nicht vorhanden sind, ist es im Grunde nur für kleine Notizen nützlich. Andernfalls müssen Sie auch einen ganzen HTML-Renderer in JS schreiben (oder betrügen und Canvas mit drawElement verwenden, was nur in Firefox unterstützt wird, an das ich mich zu erinnern scheine). Javascript ist für diese Codierungszeile wirklich nicht geeignet, wenn Sie mich fragen. Vielleicht ist es am einfachsten, einen externen Webservice anzurufen.
Jon Lennart Aasenden
JavaScript (als Sprache) liegt ganz in der Hand. JavaScript wird mit den Einschränkungen von Browsersicherheitsmodellen und APIs weniger ausgeführt.
Quentin
4
Ich bin mir sicher, dass jemand ein Haus aus Streichhölzern oder Zahnstochern bauen könnte, aber am Ende des Tages kommt ein ausgewachsener PDF-Compiler mit Unterstützung für Stitching, Grafiken, Einbettung von Schriftarten, Stilen und voll funktionsfähigen Nachschlagetabellen nicht in Frage. Schauen Sie sich die Quelle für jspdf an - sie unterstützt nur die einfachsten Tags und keine Suchwörterbücher. Ein vollständig ausgewachsener PDF-Compiler ist in C ++ oder Delphi selbst schwer zu erstellen. Eine reine JS-Implementierung wäre selbstmörderisch. Es gibt Unternehmen, die jahrelang nur ihre PDF-Compiler verkaufen (siehe zum Beispiel gnostice). Dies ist kein "One Liner".
Jon Lennart Aasenden
@ JonLennartAasenden Ja, es hat nur minimale Unterstützung. Sie können weiterhin einen PDF-Writer in js schreiben, wenn Sie möchten. Es ist jedoch keine leichte Aufgabe. Eine reine JS-Implementierung ist genauso selbstmörderisch wie C ++ oder Delphi. Tu nicht so, als wäre JS ein Bürger zweiter Klasse.
Raynos
15

Ya es ist sehr einfach mit Javascript zu tun. Hoffe, dieser Code ist nützlich für Sie.

Sie benötigen die JSpdf-Bibliothek .

<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 Link hier

Blackjoker
quelle
1
Bild nicht im PDF drucken :( Sie haben eine Lösung?
Maestro Vladimir
2
Es unterstützt weder Multiseiten noch CSS-Stile richtig.
Dynamisch
1
Unterstützt keine Tabellen :(
Liebte
3
Der JSFiddle-Link führt zu einer 404-Seite
Oscar Chambers
13

Dies mag eine späte Antwort sein, aber dies ist die beste Antwort: https://github.com/eKoopmans/html2pdf

Reine Javascript-Implementierung. Hier können Sie nur ein einzelnes Element anhand der ID angeben und konvertieren.

Billcountry
quelle
1
Keine Antwort ist spät :). Danke
Kalyan Chavali
7

Sie können Phantomjs verwenden. Laden Sie es hier herunter und testen Sie anhand des folgenden Beispiels die HTML-> PDF-Konvertierungsfunktion https://github.com/ariya/phantomjs/blob/master/examples/rasterize.js

Beispielcode:

phantomjs.exe examples/rasterize.js http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/xhtml/index.html sample.pdf
singh1469
quelle
Können Sie es mit Javascript anstelle eines Befehlszeilenprogramms verwenden?
Dynamisch
@ Dynamic nein, dies ist ein kopfloser Browser, den Sie über Javascript steuern können. Sie können festlegen, dass eine Webseite über Javascript als PDF gedruckt werden soll, die Implementierung ist jedoch kein Javascript. Verwenden Sie es jedoch für genau dieses Szenario, indem Sie es in eine App einbinden, die eine Warteschlange mit zu druckenden Seiten belegt, und ich verwende Javascript, um Einträge zur Warteschlange hinzuzufügen. Ebenso könnten Sie es in einen Dienst einwickeln. Um zu steuern, wie Dinge gedruckt werden, obwohl Sie unter der gleichen Einschränkung wie Chromdruck stehen (z. B. CSS und JS, um eine druckfreundliche Ansicht zu erstellen)
Shane
7

Ich benutzen jsPDFund dom-to-imageBibliothek zu exportieren HTML in PDF.

Ich poste hier als Hinweis auf wen Anliegen.

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

Hien Nguyen
quelle
Wenn ich in den Reaktionsmodus gehe und das PDF herunterlade, wird die PDF-Seite nicht richtig angezeigt. Gibt es eine Möglichkeit, das gleiche Ergebnis wie im Desktop-Modus zu erzielen, wenn ich im Reaktionsmodus herunterlade?
Nancy
6

Hier ist, wie ich es machen würde, es ist eine Idee, nicht kugelsicheres Design, Sie müssen es modifizieren

  • Der Benutzer klickt auf die Schaltfläche Als PDF speichern
  • Der Server erhält einen Anruf mit Ajax
  • Der Server antwortet mit einer URL für PDF, die mit HTML generiert wurde. Ich habe Apache FOP sehr erfolgreich verwendet
  • Das js, das die Ajax-Antwort verarbeitet, führt eine location.href aus, um auf die von JS gesendete URL zu verweisen. Sobald diese URL geladen wird, sendet es die Datei unter Verwendung des Inhaltsdisposition-Headers als Anhang, wodurch der Benutzer gezwungen wird, die Datei herunterzuladen.
Kumar
quelle
2

Es ist viel einfacher und zuverlässiger, HTML in PDF-Server zu konvertieren. Wir verwenden Google Puppeteer. Es ist mit Wrappern für jede serverseitige Sprache Ihrer Wahl gut gepflegt. Puppenspieler verwendet kopfloses Chrome, um Screenshots und / oder PDF-Dateien zu erstellen. Dies erspart Ihnen viel Kopfschmerzen, insbesondere wenn Sie komplexe PDF-Dateien mit Tabellen, Bildern, Grafiken, mehreren Seiten usw. erstellen müssen

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

Matej Janovčík
quelle
2

Es gibt eine andere sehr offensichtliche Möglichkeit, HTML mithilfe von JavaScript in PDf zu konvertieren: Verwenden Sie dazu eine Online-API. Dies funktioniert einwandfrei, wenn Sie die Konvertierung nicht durchführen müssen, wenn der Benutzer offline ist.

PdfMage ist eine Option, die eine schöne API hat und kostenlose Konten bietet. Ich bin sicher, Sie können viele Alternativen finden (zum Beispiel hier )

Für die PdfMage-API hätten Sie ungefähr Folgendes:

 $.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");
    }
});
Andre Borges
quelle
3
Freehtmltopdf.com scheint nicht mehr aktiv zu sein
Zach Saucier
1
PDFMage ist leider nicht mehr kostenlos.
Prometheus
1

Ja. Sie können die Lösung beispielsweise über https://grabz.it verwenden .

Es verfügt über eine Javascript-API, die auf verschiedene Arten zum Aufnehmen und Bearbeiten des Screenshots verwendet werden kann. Um es in Ihrer App zu verwenden, müssen Sie zuerst einen App-Schlüssel und ein Geheimnis erhalten und das kostenlose Javascript SDK herunterladen .

Schauen wir uns also ein einfaches Beispiel für die Verwendung an:

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

Warten Sie dann einfach eine kurze Zeit und das Bild wird automatisch am unteren Rand der Seite angezeigt, ohne dass Sie die Seite neu laden müssen.

Das ist das einfachste. Weitere Beispiele für die Bildbearbeitung, das Anhängen von Screenshots an Elemente usw. finden Sie in der Dokumentation .

Johnny
quelle
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>[email protected]</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>

Santanu
quelle
Der obige Code funktioniert in keinem von mir getesteten Browser. Wenn Sie auf die Schaltfläche "Token herunterladen" klicken, geschieht nichts und es werden keine Fehler protokolliert. Können Sie es bitte überprüfen.
Almeister9
0

Kurzum: nein. Das erste Problem ist der Zugriff auf das Dateisystem, das in den meisten Browsern aus Sicherheitsgründen standardmäßig auf no gesetzt ist. Moderne Browser unterstützen manchmal minimalistischen Speicher in Form einer Datenbank, oder Sie können den Benutzer bitten, den Dateizugriff zu aktivieren.

Wenn Sie Zugriff auf das Dateisystem haben, ist das Speichern als HTML nicht so schwierig (siehe das Dateiobjekt in der JS-Dokumentation) - aber PDF ist nicht so einfach. PDF ist ein ziemlich fortgeschrittenes Dateiformat, das für Javascript wirklich schlecht geeignet ist. Sie müssen Informationen in Datentypen schreiben, die von Javascript nicht direkt unterstützt werden, z. B. Wörter und Quads. Sie müssen auch ein Wörterbuch-Suchsystem vordefinieren, das in der Datei gespeichert werden muss. Ich bin mir sicher, dass jemand es schaffen könnte, aber der Aufwand und die Zeit, die damit verbunden sind, sollten besser für das Erlernen von C ++ oder Delphi aufgewendet werden.

Der HTML-Export sollte jedoch möglich sein, wenn der Benutzer Ihnen uneingeschränkten Zugriff gewährt

Jon Lennart Aasenden
quelle
2
Warum können C ++ und Delphi einen PDF-Writer von Natur aus besser erstellen?
Raynos
2
Weil diese Sprachen für fortschrittliche Software entwickelt wurden. Javascript war nicht. Javascript wurde nie fertiggestellt, deshalb hängt das Prototypensystem rum. Der Autor hatte geplant, einen HL mit realen Klassen und mehr Datentypen hinzuzufügen - aber er hatte keine Zeit. So wurde es "wie es ist" veröffentlicht. Es unterstützt keine Zeiger, die Zuweisung des Rohspeichers ist schmerzhaft, es unterstützt einige der nativen Datentypen, die Sie in anderen Sprachen finden, nicht, es unterstützt keine gepackten Strukturen (Struktur in C, Datensatz in Pascal) ... die Liste ist endlos. Ich liebe JS, aber es ist ein Browser-Spielzeug, keine echte Sprache.
Jon Lennart Aasenden
Es gibt einige Java-basierte Autoren, und wenn man sich die Größe des Quellcodes ansieht, sollte es ziemlich selbstverständlich sein, dass es unter Javascript noch länger dauern würde - aber der entscheidende Punkt ist: die IO-Formatierung und die Nachschlagetabellen . Ich bin mir sicher, dass jemand es schaffen könnte - aber es wäre extrem langsam und im Grunde eine Zeitverschwendung. Und wie werden Sie Schriftdaten einbetten? Sie können die Datei nicht einmal vom Betriebssystem abrufen, geschweige denn konvertieren (was eine ganze Bibliothek für sich ist) und einbetten. Warum ein Streichholzhaus bauen, wenn man nur ein normales Haus bauen kann?
Jon Lennart Aasenden
2
"Aber es ist ein Browser-Spielzeug, keine echte Sprache." Das ist so, als würde man sagen, dass Schema keine echte Sprache ist. "Es sollte ziemlich selbstverständlich sein, dass es unter Javascrip noch länger dauern würde", nein. Java ist wesentlich ausführlicher als JavaScript. Es sollte ungefähr 2/3 kürzer sein als die Java-Version. "aber es wäre extrem langsam und im Grunde" Mit extrem langsam meinst du 3 / 4x langsamer als C ++? Können wir bitte aufhören, js als Bürger zweiter Klasse zu behandeln? Vielen Dank.
Raynos
11
Unabhängig von Ihrer persönlichen Meinung, Jon, könnten Sie aufhören, die Behauptung aufzustellen, dass "Javascript keine echte Sprache ist", denn das ist BS. Javascript ist eine äußerst leistungsfähige Sprache, die für andere Zwecke optimiert ist als eine kompilierte Sprache auf niedriger Ebene wie C oder C ++. Es gibt Dinge, die Sie in JS tun können, die Sie in C oder C ++ nicht tun können, aber bedeutet das, dass C und C ++ keine "echten" Sprachen sind? Nein, nur dass sie für verschiedene Dinge gedacht sind. JS ist eine ebenso echte Programmiersprache wie jede andere vollständige Sprache.
Isochronous