使用 iText 将 HTML 转换为 PDF源文件:我遇到的问题:剩下的问题:附加问题:为什么你的代码不起作用如何解决问题一些额外的想法。
我发布这个问题是因为许多开发人员以不同的形式或多或少地提出相同的问题。我会自己回答这个问题(我是iText Group的创始人/首席技术官),这样它就可以成为一个“Wiki-answer”。如果 Stack Overflow “文档”功能仍然存在,这将是文档主题的良好候选者。
源文件:
我正在尝试将以下HTML文件转换为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>
在浏览器中,此 HTML 如下所示:
我遇到的问题:
HTMLWorker根本没有考虑CSS。
当我使用时,我需要创建一个以避免错误,通知我找不到图像。我还需要创建一个实例来更改一些样式:HTMLWorker
ImageProvider
StyleSheet
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();
}
结果如下所示:
出于某种原因,还会显示标记的内容。我不知道如何避免这种情况。标头中的CSS根本没有被解析,我必须使用对象在代码中定义所有样式。HTMLWorker
<title>
StyleSheet
当我查看我的代码时,我看到我正在使用的大量对象和方法都被弃用了:
因此,我决定升级到使用 XML Worker。
使用 XML 工作线程时找不到图像
我尝试了以下代码:
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();
}
这导致了以下 PDF:
而不是Times-Roman,使用默认字体Helvetica;这是典型的iText(我应该在我的HTML中明确定义一种字体)。否则,CSS似乎受到尊重,但图像丢失,我没有收到错误消息。
有 ,则抛出异常,我能够通过引入 .让我们看看这是否适用于 XML Worker。HTMLWorker
ImageProvider
并非所有 CSS 样式在 XML Worker 中都受支持
我像这样调整了我的代码:
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();
}
我的代码要长得多,但现在图像被渲染了:
图像比我使用它时大,这告诉我类的CSS属性被考虑在内,但该属性被忽略。如何解决此问题?HTMLWorker
width
poster
float
剩下的问题:
所以问题归结为:我有一个特定的HTML文件,我试图将其转换为PDF。我经历了很多工作,修复了一个又一个问题,但有一个具体的问题我无法解决:我如何使iText尊重定义元素位置的CSS,例如?float: right
附加问题:
当我的 HTML 包含表单元素(如 )时,这些表单元素将被忽略。<input>