在我们开始之前:我不是 C# 开发人员,所以我无法给您提供 C# 示例。我编写的所有 iText 示例都是用 Java 编写的。幸运的是,iText 和 iTextSharp 始终保持同步。在这个问题的上下文中,您可以放心,适用于 iText 的任何内容也适用于 iTextSharp,但您必须进行特定于 C# 的小调整。据我从 C# 开发人员那里听到的消息,这通常并不难实现。
关于答案:有两个答案,答案#2 通常比答案#1 更好,但我给出这两个选项,因为可能在某些特定情况下答案#1 更好。
测试数据:我创建了 3 个简单的 HTML 文件,每个文件都包含有关美国某个州的一些信息:
-
第1页.html http://itextpdf.com/sites/default/files/page1.html: 加利福尼亚州
-
page2.html http://itextpdf.com/sites/default/files/page2.html: 纽约
-
page3.html http://itextpdf.com/sites/default/files/page3.html:马萨诸塞州
我们将使用 XML Worker 来解析这三个文件,并希望得到一个 PDF 文件。
答案#1: see 解析多个Html文件1 http://itextpdf.com/sandbox/xmlworker/ParseMultipleHtmlFiles1完整的代码示例和multiple_html_pages1.pdf http://itextpdf.com/sites/default/files/multiple_html_pages1.pdf对于生成的 PDF。
您说您已经成功将一个 HTML 文件转换为一个 PDF 文件。假设您是这样做的:
public byte[] parseHtml(String html) throws DocumentException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, baos);
// step 3
document.open();
// step 4
XMLWorkerHelper.getInstance().parseXHtml(writer, document,
new FileInputStream(html));
// step 5
document.close();
// return the bytes of the PDF
return baos.toByteArray();
}
这不是解析 HTML 文件的最有效方法(网站上还有其他示例),但它是最简单的方法。
正如您所看到的,此方法将 HTML 解析为 PDF 文件,并以以下形式返回该 PDF 文件:byte[]
。由于我们想要创建一个 PDF,我们可以将此字节数组提供给PdfCopy
实例,以便我们可以连接多个文档。
假设我们有三个文档:
public static final String[] HTML = {
"resources/xml/page1.html",
"resources/xml/page2.html",
"resources/xml/page3.html"
};
我们可以循环这三个文档,将它们一一解析为byte[]
, 创建一个PdfReader
实例与 PDF 字节,并将文档添加到PdfCopy
实例使用addDocument()
method:
public void createPdf(String file) throws IOException, DocumentException {
Document document = new Document();
PdfCopy copy = new PdfCopy(document, new FileOutputStream(file));
document.open();
PdfReader reader;
for (String html : HTML) {
reader = new PdfReader(parseHtml(html));
copy.addDocument(reader);
reader.close();
}
document.close();
}
这解决了您的问题,但为什么我认为这不是最佳解决方案?
假设您需要使用需要嵌入的特殊字体。在这种情况下,每个单独的 PDF 文件都将包含该字体的子集。不同的文件需要不同的字体子集,并且PdfCopy
(nor PdfSmartCopy
就此而言)可以合并字体子集。这可能会导致 PDF 文件臃肿,其中包含太多相同字体的字体子集。
我们如何解决这个问题?答案#2 对此进行了解释。
答案#2: See 解析多个Html文件2 http://itextpdf.com/sandbox/xmlworker/ParseMultipleHtmlFiles2完整的代码示例和multiple_html_pages2.pdf http://itextpdf.com/sites/default/files/multiple_html_pages2.pdf对于生成的 PDF。您已经看到文件大小的差异:4.61 KB 与 5.05 KB(我们甚至没有引入嵌入字体)。
在这种情况下,我们不会像在中那样将 HTML 解析为 PDF 文件parseHtml()
答案#1 中的方法。相反,我们将 HTML 解析为 iTextElementList
使用parseToElementList()
方法。该方法需要两个String
s。一个包含 HTML 代码,另一个包含 CSS 值。
我们使用实用方法将 HTML 文件读入String
。至于CSS值,我们可以通过null
to parseToElementList()
,但在这种情况下,默认样式将被忽略。你会注意到<h1>
如果你不通过,我们在 HTML 中引入的标签看起来会完全不同default.css
随 XML Worker 一起提供。
长话短说,这是代码:
public void createPdf(String file) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(file));
document.open();
String css = readCSS();
for (String htmlfile : HTML) {
String html = Utilities.readFileToString(htmlfile);
ElementList list = XMLWorkerHelper.parseToElementList(html, css);
for (Element e : list) {
document.add(e);
}
document.newPage();
}
document.close();
}
我们创建一个单一的Document
和一个单一的PdfWriter
实例。我们将不同的 HTML 文件解析为ElementList
s 一个接着一个,然后我们将所有元素添加到Document
.
当你想要一个新页面时,每次解析一个新的 HTML 文件时,我引入了一个document.newPage()
。如果删除此行,则可以将三个 HTML 页面添加到单个页面上(如果您选择答案#1,则这是不可能的)。