Ich versuche verzweifelt, ein von phantomJS generiertes PDF auszugeben, wie hier
Was ich bekomme, ist eine leere PDF-Datei, obwohl sie nicht 0 ist, zeigt sie eine leere Seite an.
%Vor% Und ich nenne es so: phantomjs rasterize.js http://google.com>test.pdf
Ich habe versucht, /dev/stdout
in system.stdout
zu ändern, aber nicht Glück. PDF direkt in Datei zu schreiben funktioniert ohne Probleme.
Ich suche nach einer plattformübergreifenden Implementierung, also hoffe ich, dass dies auf nicht-Linux-Systemen erreichbar ist.
Beim Schreiben der Ausgabe in /dev/stdout/
oder /dev/stderr/
unter Windows durchläuft PhantomJS
die folgenden Schritte (wie in der Methode render
in \ phantomjs \ src \ webpage.cpp ):
/dev/stdout/
und /dev/stderr/
wird ein temporärer Dateipfad zugewiesen. renderPdf
mit dem temporären Dateipfad auf. QByteArray
. QString::fromAscii
im Bytearray auf und schreiben Sie in stdout
oder stderr
. Zunächst habe ich die Quelle für PhantomJS
erstellt, aber die Löschung der Datei auskommentiert. Beim nächsten Durchlauf konnte ich die temporäre Datei untersuchen, die sie gerendert hatte, was sich als völlig in Ordnung erwies. Ich habe auch versucht, phantomjs.exe rasterize.js http://google.com > test.png
mit denselben Ergebnissen auszuführen. Dies schloss ein Rendering-Problem oder irgendetwas, das speziell mit PDFs zu tun hatte, sofort aus, was bedeutete, dass das Problem damit zusammenhängen musste, wie Daten in stdout
geschrieben wurden.
Zu diesem Zeitpunkt hatte ich Verdacht, ob es Text-Encoding-Shenanigans gab. Von früheren Läufen hatte ich sowohl eine gültige als auch eine ungültige Version derselben Datei (in diesem Fall ein PNG).
Unter Verwendung eines C # -Codes habe ich das folgende Experiment ausgeführt:
%Vor% Beachten Sie, dass ich die ISO-8859-1-Codierung verwendet habe, da QT
dies als Standardeinstellung verwendet Kodierung für C-Strings . Wie sich herausstellte, waren alle diese Bytes gleich. Der Zweck dieser Übung bestand darin, zu sehen, ob ich die Kodierungsschritte nachahmen könnte, die dazu führten, dass gültige Daten ungültig wurden.
Für weitere Beweise untersuchte ich \ phantomjs \ src \ system.cpp und \ phantomjs \ src \ filesystem.cpp .
system.cpp
enthält die Klasse System
unter anderem File
-Objekte für stdout
, stdin
und stderr
, die für die Verwendung von UTF-8
encoding. stdout
wird die Funktion write
des Objekts File
aufgerufen. Diese Funktion unterstützt das Schreiben sowohl in Text- als auch in Binärdateien. Wegen der Art und Weise, wie die System
-Klasse sie initialisiert, werden alle Schreibvorgänge so behandelt, als würden sie in eine Textdatei gehen. Also läuft das Problem darauf hinaus: Wir müssen eine binäre Schreiboperation auf stdout
durchführen, doch unsere Schreiboperationen werden als Text behandelt und eine Codierung angewendet, die dazu führt, dass die resultierende Datei ungültig wird.
Angesichts des oben beschriebenen Problems sehe ich keinen Weg, wie dies unter Windows so funktioniert, wie Sie es wollen, ohne Änderungen am PhantomJS
-Code vorzunehmen. Also hier sind sie:
Diese erste Änderung wird eine Funktion bereitstellen, die wir auf File
-Objekten aufrufen können, um explizit einen binären Schreibvorgang auszuführen.
Fügen Sie den folgenden Funktionsprototyp in \phantomjs\src\filesystem.h
hinzu:
Und setze seine Definition in \phantomjs\src\filesystem.cpp
(der Code für diese Methode stammt von der Methode write
in dieser Datei):
Um die Zeile 920 von \phantomjs\src\webpage.cpp
sehen Sie einen Codeblock, der folgendermaßen aussieht:
Ändern Sie es zu diesem:
%Vor% Also, was dieser Code-Ersatz tut, ruft unsere neue binaryWrite
-Funktion auf, wird aber durch einen #ifdef Q_OS_WIN32
-Block geschützt. Ich habe es so gemacht, um die alte Funktionalität auf Nicht-Windows-Systemen beizubehalten, die dieses Problem nicht zu zeigen scheinen (oder nicht?). Beachten Sie, dass dieser Fix nur für das Schreiben in stdout
gilt - wenn Sie möchten, können Sie ihn immer auf stderr
anwenden, aber das ist in diesem Fall nicht so wichtig.
Falls Sie nur eine vordefinierte Binärdatei haben möchten (wer nicht?), können Sie phantomjs.exe
mit diesen Korrekturen auf meiner SkyDrive . Meine Version ist ungefähr 19 MB, wohingegen die, die ich vorher heruntergeladen habe, nur ungefähr 6 MB groß war, obwohl ich die Anweisungen hier befolgt habe, also sollte es in Ordnung sein .
Ja, das stimmt. ISO-8859-1 ist die Standardcodierung für QT, daher müssen Sie der Befehlszeile den erforderlichen Parameter hinzufügen --output-encoding = ISO-8859-1, damit die PDF-Ausgabe nicht erfolgt beschädigt
d.
phantomjs.exe rasterize.js - Ausgangscodierung = ISO-8859-1 & lt; input.html & gt; output.pdf
und rasterize.js sieht so aus (getestet, funktioniert für Unix und Windows)
%Vor%oder alternativ können Sie die Kodierung mit stdout einstellen und wenn Sie vom UTF-8-Stream lesen, müssen Sie möglicherweise auch die Kodierung für stdin einstellen;
%Vor%Ist es zwingend erforderlich, das PDF auf stdout auszugeben? Könntest du den Code nicht in:
ändern? %Vor%und benutze es so:
%Vor%Tags und Links javascript pdf stdout phantomjs