Konvertieren von HTML in PDF mit iText
Ich bin Entsendung diese Frage, weil viele Entwickler Fragen mehr oder weniger die gleiche Frage in verschiedenen Formen. Ich beantworte diese Frage selbst (ich bin der Gründer/CTO von iText Gruppe), so dass es sein kann, ein "Wiki-Antwort." Wenn der Stack-Überlauf "Dokumentation" - Funktion noch existiert, dies wäre ein guter Kandidat für eine Dokumentation Thema.
Der Quell-Datei:
Ich versuche, konvertieren Sie die folgende HTML-Datei in PDF:
<html>
<head>
<title>Colossal (movie)</title>
<style>
.poster { width: 120px;float: right; }
.director { font-style: italic; }
.description { font-family: serif; }
.imdb { font-size: 0.8em; }
a { color: red; }
</style>
</head>
<body>
<img src="img/colossal.jpg" class="poster" />
<h1>Colossal (2016)</h1>
<div class="director">Directed by Nacho Vigalondo</div>
<div class="description">Gloria is an out-of-work party girl
forced to leave her life in New York City, and move back home.
When reports surface that a giant creature is destroying Seoul,
she gradually comes to the realization that she is somehow connected
to this phenomenon.
</div>
<div class="imdb">Read more about this movie on
<a href="www.imdb.com/title/tt4680182">IMDB</a>
</div>
</body>
</html>
In einem browser, der dieses HTML sieht wie folgt aus:
Die Probleme, die ich gestoßen:
HTMLWorker nicht der CSS berücksichtigen überhaupt
Wenn ich HTMLWorker
brauche ich zum erstellen einer ImageProvider
um einen Fehler vermeiden, informiert mich, dass das Bild nicht gefunden werden kann. Ich muss auch zum erstellen einer StyleSheet
Instanz zu ändern einige Formatvorlagen:
public static class MyImageFactory implements ImageProvider {
public Image getImage(String src, Map<String, String> h,
ChainedProperties cprops, DocListener doc) {
try {
return Image.getInstance(
String.format("resources/html/img/%s",
src.substring(src.lastIndexOf("/") + 1)));
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
public static void main(String[] args) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("results/htmlworker.pdf"));
document.open();
StyleSheet styles = new StyleSheet();
styles.loadStyle("imdb", "size", "-3");
HTMLWorker htmlWorker = new HTMLWorker(document, null, styles);
HashMap<String,Object> providers = new HashMap<String, Object>();
providers.put(HTMLWorker.IMG_PROVIDER, new MyImageFactory());
htmlWorker.setProviders(providers);
htmlWorker.parse(new FileReader("resources/html/sample.html"));
document.close();
}
Das Ergebnis sieht wie folgt aus:
Aus irgendeinem Grund HTMLWorker
zeigt auch den Inhalt der <title>
tag. Ich weiß nicht, wie dies zu vermeiden. Die CSS-Datei in der Kopfzeile nicht analysiert an alle, ich haben, definieren Sie die Stile in meinem code, mit dem StyleSheet
Objekt.
Wenn ich mir meinen code sehe ich, dass viele Objekte und Methoden, die ich verwende sind veraltet:
Also habe ich beschlossen, ein upgrade auf die Verwendung von XML-Arbeiter.
Bilder nicht gefunden werden, wenn die Verwendung von XML Worker
Habe ich versucht den folgenden code:
public static final String DEST = "results/xmlworker1.pdf";
public static final String HTML = "resources/html/sample.html";
public void createPdf(String file) throws IOException, DocumentException {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
document.open();
XMLWorkerHelper.getInstance().parseXHtml(writer, document,
new FileInputStream(HTML));
document.close();
}
Dies führte in der folgenden PDF-Datei:
Anstelle von Times Roman, der Standard-schriftart Helvetica verwendet wird; dies ist typisch für iText (ich sollte definiert eine schriftart, die explizit in meinem HTML). Ansonsten werden die CSS scheint, respektiert zu werden, aber das Bild fehlt, und ich nicht eine Fehlermeldung erhalten.
Mit HTMLWorker
, wird eine Ausnahme geworfen wurde, und ich war in der Lage, das problem zu beheben durch die Einführung einer ImageProvider
. Mal sehen, ob das funktioniert für XML Worker.
Nicht alle CSS-Stile werden unterstützt XML-Worker
Angepasst ich meinen code wie folgt:
public static final String DEST = "results/xmlworker2.pdf";
public static final String HTML = "resources/html/sample.html";
public static final String IMG_PATH = "resources/html/";
public void createPdf(String file) throws IOException, DocumentException {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
document.open();
CSSResolver cssResolver =
XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
htmlContext.setImageProvider(new AbstractImageProvider() {
public String getImageRootPath() {
return IMG_PATH;
}
});
PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.parse(new FileInputStream(HTML));
document.close();
}
Mein code ist viel länger, aber jetzt wird das Bild gerendert:
Das Bild größer ist, als wenn ich es gerendert mit HTMLWorker
was mir sagt, dass das CSS-Attribut width
für die poster
Klasse berücksichtigt, aber die float
- Attribut ignoriert. Wie kann ich dieses Problem beheben?
Bleibt die Frage:
Also die Frage läuft darauf hinaus, diese: ich habe einen bestimmten HTML-Datei, die ich versuche, in PDF zu konvertieren. Ich habe gegangen durch eine Menge von Arbeit, die Befestigung ein problem nach dem anderen, aber es ist eine bestimmten problem, dass ich nicht lösen kann: wie kann ich machen iText Respekt CSS, definiert die position eines Elements, wie float: right
?
Zusätzliche Frage:
Wenn meine HTML enthält die Elemente bilden (wie <input>
), die form-Elemente werden ignoriert.
Denn es gibt nicht ein spezifische Frage. Ungefragt "Frage" hier ist, wie konvertiere ich diese HTML-zu PDF. Die ganze Sache ist zu breit. Und der gesamte Stil scheint eine schlechte Passform für das format, diese Dokumentation nicht.
Sie müssen auch nicht offenlegen, Ihre Verbundenheit mit der Bibliothek in der "Frage" oder "Antwort".
OK, die updates sind gemacht (die konkrete Frage + die Zugehörigkeit zu iText-Gruppe). Sind Sie jetzt glücklich, @jmoerdyk?
Es gibt bereits viele Hinweise auf diese Frage in den Kommentaren: stackoverflow.com/questions/47872246 stackoverflow.com/questions/47852780 stackoverflow.com/questions/47830668 stackoverflow.com/questions/47787253 stackoverflow.com/questions/47808275, Wie viele Fragen sollte ich hinzufügen, Sie zu überzeugen, dass dieses Q&A sind nützlich? Wenn ich kann nicht Sie überzeugen, bitte Wiedereinführung der SO-Dokumentation der Funktionalität, so dass ich hinzufügen kann, diese Inhalte als eine Dokumentation, ein Thema (oder eine alternative Lösung).
InformationsquelleAutor Bruno Lowagie | 2017-12-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
, Warum der code nicht funktioniert
Wie in der Einführung erläutert der HTML-zu-PDF-tutorial,
HTMLWorker
ist veraltet, vor vielen Jahren. Es war nicht beabsichtigt, konvertieren Sie komplette HTML-Seiten. Er weiß nicht, dass eine HTML-Seite hat eine<head>
und ein<body>
Abschnitt; es analysiert alle Inhalte. Es war dazu gedacht, zu analysieren, kleine HTML-Schnipsel, und definieren Sie die Stile mit Hilfe derStyleSheet
Klasse; echte CSS nicht unterstützt.Dann kam XML-Arbeiter. XML Worker war gemeint als generisches framework, um XML zu Parsen. Als proof-of-concept, beschlossen wir schreiben XHTML, um PDF-Funktionalität, aber wir haben nicht alle HTML-tags. Zum Beispiel: Formulare nicht unterstützt, und es war sehr schwer, CSS zu unterstützen, wird verwendet, um die position content. Formulare in HTML sind sehr Verschieden von Formularen in PDF. Es wurde auch ein Missverhältnis zwischen der iText-Architektur und der Architektur von HTML + CSS. Allmählich erweiterten wir XML Arbeiter, meist basierend auf Anfragen von Kunden, aber XML-Arbeiter wurde ein monster mit vielen Tentakeln.
Irgendwann haben wir beschlossen zu umschreiben, iText, von Grund auf, mit den Anforderungen für HTML + CSS Konvertierung in den Sinn. Dies führte zu iText 7. Auf der Oberseite der iText 7, erstellten wir mehrere add-ons, die wichtigsten in diesem Zusammenhang wird pdfHTML.
, Wie das problem zu lösen
Mit der neuesten version von iText (iText 7.1.0 + pdfHTML 2.0.0) der code zum konvertieren der HTML-Code aus der Frage zu PDF ist reduziert auf dieses snippet:
Das Ergebnis sieht wie folgt aus:
Wie Sie sehen können, ist dies ziemlich genau dem Ergebnis, das Sie erwarten würde. Da iText 7.1.0 /pdfHTML 2.0.0, die Standard-schriftart ist Times-Roman. Die CSS wird gewahrt: das Bild ist jetzt schwimmt auf der rechten Seite.
Einige zusätzliche Gedanken.
Entwickler oft das Gefühl, im Gegensatz zu einem upgrade auf eine neuere iText version wenn ich die Beratung für ein upgrade auf iText 7 /pdfHTML 2. Erlauben Sie mir zu beantworten, um die top-3 Argumente, die ich höre:
Ich die freie iText, und iText 7 ist nicht kostenlos /die pdfHTML add-on ist closed source.
iText 7 veröffentlicht wird, mit der AGPL, wie iText 5 und XML-Arbeiter. Der AGPL erlaubt die Kostenlose Nutzung im Sinne von kostenlos im Kontext von open-source-Projekte. Wenn Sie verteilen eine closed-source /proprietär Produkt (z.B. Sie verwenden, iText in einer SaaS-Umgebung), können Sie nicht verwenden, iText kostenlos; in diesem Fall müssen Sie eine kommerzielle Lizenz erwerben. Das gilt schon für iText 5; dies gilt noch immer für iText 7. Für Versionen vor iText 5: Sie sollten nicht verwenden, diese an alle. Bezüglich pdfHTML: die ersten Versionen waren in der Tat nur als closed-source-software. Wir hatten schwere Diskussionen innerhalb des iText-Gruppe: auf der einen Seite gab es die Leute, die vermeiden wollten, dass der massive Missbrauch von Unternehmen, die nicht Zuhören, um Ihre Entwickler, wenn die Entwickler sagen, die Kräfte, die open source ist nicht gleich kostenlos. Die Entwickler haben uns gesagt, dass Ihr Chef Sie gezwungen, das falsche zu tun, und das konnten Sie nicht überzeugen, Ihren Chef, um eine kommerzielle Lizenz zu erwerben. Auf der anderen Seite gab es Leute, die argumentieren, wir sollten nicht bestraft werden, die Entwickler für das falsche Verhalten Ihrer Chefs. Schließlich, die Menschen zu Gunsten von open Source pdfHTML, das ist: die Entwickler bei iText, gewann das argument. Beweisen Sie bitte, dass Sie waren nicht falsch, und verwenden iText richtig: respektieren Sie die AGPL wenn Sie mit iText kostenlos; stellen Sie sicher, dass Ihr Chef kommerzielle Lizenz erwerben, wenn Sie mit iText in ein closed-source-Kontext.
Ich halten müssen, um ein legacy-system, und ich habe, um eine alte iText version.
Ernst? Die Wartung beinhaltet auch das anwenden von upgrades und die Migration zu neuen Versionen der software, die Sie verwenden. Wie Sie sehen können, benötigt der code bei der Verwendung von iText 7 und pdfHTML ist sehr einfach und weniger fehleranfällig ist, als der code, der benötigt vor. Ein Migrations-Projekt sollte nicht allzu lange dauern.
Ich habe gerade erst angefangen und ich wusste nicht, über iText 7; ich fand erst heraus, nachdem ich mein Projekt.
Deshalb bin ich Entsendung diese Frage und die Antwort. Denke, von sich selbst als eXtreme Programmer. Werfen Sie alle Ihre code ein, und beginnen Sie von neuem. Sie werden bemerken, dass es nicht so viel Arbeit wie du dir vorgestellt hast, und du wirst besser schlafen zu wissen, dass Sie gemacht haben, Ihr Projekt zukunftssicher, weil iText 5 ist ein Auslaufmodell. Wir bieten immer noch Unterstützung für zahlende Kunden, aber irgendwann werden wir nicht mehr unterstützen iText 5 insgesamt.
Guter Fang, @mkl, der text sagt das Gegenteil von dem, was ich meinte.
Hallo @Bruno, danke für die Antwort, aber ich habe eine weitere Voraussetzung für die Umwandlung der gleichen html-Seite in excel geschieht dies mit ItextSharp-7
Nein, es würde mich Wundern, wenn Sie finden konnte, ein Werkzeug, konvertieren von beliebigen web-Seite nach Excel. HTML-und Excel haben völlig verschiedene Zwecke. Nehmen Sie zum Beispiel die Seite lowagie.com Was würde die Seite Aussehen wie in Excel? Wäre es sinnvoll, Sie zu konvertieren, so eine Seite zu zeichnen? (Nein, es würde nicht.)
die Datei hat eine Größe von fast 1 GB". Wow, ich hoffe, Sie beziehen sich nicht nur html -, sondern auch die Größe der Bilder und Dateien verbunden und ich Frage mich, ob Sie wirklich brauchen diese riesigen fles im PDF-Dokument eingebettet. Vielleicht ein link zu einem corporate - /public-server statt?
InformationsquelleAutor Bruno Lowagie