itext7.pdfhtml For C#

发布时间 2023-09-27 18:39:49作者: 该昵称已被屏蔽

最近发现 itext7 (前身为iTextSharp) 下有个 https://github.com/itext/i7n-pdfhtml 的项目可以支持html转PDF

下面是官方电子书的翻译内容,原文地址:Chapter 1: Hello HTML to PDF --- 第 1 章:你好 HTML 到 PDF (itextpdf.com)

第 1 章:你好 HTML 到 PDF

在本章中,我们将以许多不同的方式将简单的HTML文件转换为PDF文档。HTML文件的内容将包括一个“Test”标题,一个“Hello World”段落和一个代表iText logo的图像。

示例的结构

本书中的所有示例都将具有类似的结构。

INPUT:  

对于输入,我们将提供 HTML 语法。在本教程中,我们将使用 HTML 字符串、HTML 文件的路径,或者(在第 4 章中)使用 XML 文件的路径以及 XSLT 文件的路径,将 XML 转换为 HTML。

在第一个示例中,HTML以字符串形式提供  :

public String HTML = "<h1>Test</h1><p>Hello World</p>";

在其他示例中,我们将使用两个常量:

  • BASEURI常量,用于查找源HTML和 resources(如图像和CSS)的父文件夹的路径
  • SRC常量,其中包含该源HTML文件的路径

 例如: 

public static string BASEURI = "src/main/resources/html/";
public static string SRC = string.Format("{0}hello.html", BASEURI);

OUTPUT:

我们将对输出使用类似的结构:

  • TARGET 常量,用于写入生成的PDF的文件夹的路径
  • 带有该 PDF 路径的 DEST 常量

例如:

public static string TARGET = "target/results/ch01/";
public static string DEST = string.Format("{0}test-03.pdf", TARGET);

主要方法:

本书中所有示例的主要方法与我们第一个示例的方法没有太大区别:

static void Main(string[] args)
{
    LicenseKey.LoadLicenseFile(
        Environment.GetEnvironmentVariable("ITEXT-7_LICENSEKEY") + "\\itextkey-html2pdf_typography.xml"
    );
    Directory.CreateDirectory(BASEURI);
    CreatePdf(HTML, DEST);
}

首先我们加载 iText 许可证文件。这是一个 XML 文件,包含使用 iText 的许可证密钥。如果您在 AGPL 项目上下文中使用 iText 和 pdfHTML,您可能不需要此许可证密钥。但是,第 6 章中的国际化示例需要 pdfCalligraph 插件,而 pdfCalligraph 插件在 AGPL 下不可用;它只是一个闭源附加组件。

我们在本书示例中使用的许可证密钥与您购买商业许可证以在闭源环境中使用 iText 7、pdfHTML 和 pdfCalligraph 时获得的密钥类似。请注意,从 iText 7.2 开始,我们的许可证密钥文件现在使用 JSON 格式而不是 XML。有关更多说明,您可以参阅许可证密钥和许可证密钥库安装指南。

然后我们创建目标目录(如果它还不存在),然后是 CreatePdf() 方法。我们可以通过许多不同的方式实现此方法。

将 HTML 转换为 PDF 

示例的 createPdf() / CreatePdf() 方法的实现非常简单。它的主体由一行组成:

public void CreatePdf(string html, string dest)
{
    HtmlConverter.ConvertToPdf(html, new FileStream(dest, FileMode.Create));
}

该 HtmlConverter 对象有一系列不同的静态 convertToPdf() / ConvertToPdf() 方法选择,这些方法根据用例采用不同的参数。在第一个示例中,第一个参数html是一个字符串,其值如下:

public string HTML = "<h1>Test</h1><p>Hello World</p>";

将 HTML 代码段转换为 PDF如下:

接下来引入一个图像,使用以下内容:

public static string HTML = "<h1>Test</h1><p>Hello World</p><img src=\"img/logo.png\">";

此 HTML 代码段包含指向 img 子目录中的图像文件 logo.png 的相对链接。iText 无法猜测在哪里查找此子目录,因此我们将为转换过程配置基本 URI。

这是使用 ConverterProperties 完成的,如下CreatePdf()方法所示:

public void CreatePdf(string baseUri, string html, string dest)
{
    ConverterProperties properties = new ConverterProperties();
    properties.SetBaseUri(baseUri);
    HtmlConverter.ConvertToPdf(html, new FileStream(dest, FileMode.Create), properties);
}

创建一个 ConverterProperties 对象,并将基本URI设置为iText可以找到 logo.png 文件的目录的 img 的父目录。

转换结果如下:

 在下面的大多数示例中,我们不会使用存储在字符串中的HTML,我们将把磁盘上的 HTML 文件转换为磁盘上的文件。

对于本章中的其余示例,将使用下图所示的文件 hello.html :

有多种方法可以将此文件转换为 PDF 文档。

在如下示例中,我们使用 File / FileInfo 对象:

public void CreatePdf(string src, string dest)
{
    HtmlConverter.ConvertToPdf(new FileInfo(src), new FileInfo(dest));
}

ConvertToPdf() 方法的第一个参数引用源 HTML 文件,第二个参数引用目标 PDF 文件。在这种情况下,我们不需要设置任何转换器属性。默认情况下,iText 将使用此文件的父目录作为基本 URI。

 在如下示例中,我们使用 FileInputStream/FileStream和FileOutputStream/FileStream 对象:

public void CreatePdf(string baseUri, string src, string dest)
{
    ConverterProperties properties = new ConverterProperties();
    properties.SetBaseUri(baseUri);
    HtmlConverter.ConvertToPdf(new FileStream(src, FileMode.Open), new FileStream(dest, FileMode.Create));
}

这是一个关于PDF压缩的示例:

public void CreatePdf(string baseUri, string src, string dest)
{
    ConverterProperties properties = new ConverterProperties();
    properties.SetBaseUri(baseUri);
    PdfWriter writer = new PdfWriter(dest,new WriterProperties().SetFullCompressionMode(true));
    HtmlConverter.ConvertToPdf(new FileStream(src, FileMode.Open), writer, properties);
}

在这种情况下,我们使用 PdfWriter 而不是 FileOutputStream / FileStream 。如果要设置某些编写器属性,则使用 PdfWriter 可能很有用。

For more information on writer properties, please read Chapter 7 of the iText 7: Building Blocks tutorial, entitled "Handling events; setting viewer preferences and printer properties."

在此示例中,我们以完全压缩模式创建 PDF。对于人眼来说,生成的 PDF 看起来是相同的,但是当您将前面生成的 PDF 的文件大小与本示例中生成的 PDF 的文件大小进行比较时,您会发现压缩为我们赢得了一些字节。

在下面的示例中,我们将 PdfWriter 替换为 PdfDocument (Java/.NET) 参数。

public void CreatePdf(string baseUri, string src, string dest)
{
    ConverterProperties properties = new ConverterProperties();
    properties.SetBaseUri(baseUri);
    PdfWriter writer = new PdfWriter(dest);
    PdfDocument pdf = new PdfDocument(writer);
    pdf.SetTagged();
    HtmlConverter.ConvertToPdf(new FileStream(src, FileMode.Open), pdf, properties);
}

如果要在 PdfDocument 层配置feature,则使用 PdfDocument 实例是有意义的。在本例中,我们引入 pdf.setTagged(),它指示 iText 创建带标签的 PDF。

如图展示了带标签的 PDF:

 将鼠标悬停在图像上时,您会看到 <img> -tag 的 alt 属性值作为工具提示。

For more info on Tagged PDF, please read Chapter 7 (Java/.NET) of the iText 7: Jump-Start Tutorial (Java/.NET), entitled "Creating PDF/UA and PDF/A documents."

将 HTML 转换为 iText 对象

ConvertToPdf() 方法创建一个完整的 PDF 文件。一旦分析输入并将其转换为PDF,那么传递给 ConvertToPdf 方法的任何File、FileInfo、OutputStream、PdfWriter或PdfDocument都将关闭。但这可能并不总是你想要的。

在某些情况下,您希望向 Document 添加一些额外的信息,或者您可能不想将 HTML 转换为 PDF 文件,而是转换为一系列可用于不同目的的 iText 对象。而这就是 ConvertToDocument()和ConvertToElements() 方法的意义所在。

在这个示例中,我们将 Hello World HTML 转换为 Document ,因为我们希望在解析完 HTML 后添加一些额外的内容:

public void CreatePdf(string baseUri, string src, string dest)
{
    ConverterProperties properties = new ConverterProperties();
    properties.SetBaseUri(baseUri);
    PdfWriter writer = new PdfWriter(dest);
    PdfDocument pdf = new PdfDocument(writer);
    Document document = HtmlConverter.ConvertToDocument(new FileStream(src, FileMode.Open), pdf, properties);
    document.Add(new Paragraph("Goodbye!"));
    document.Close();
}

ConvertToDocument()方法返回一个 iText Document 实例。我们使用这个 Document 实例在解析HTML之后添加一些额外的内容( "Goodbye!" )

结果如下图:

上图中内容的上半部分是通过将 HTML 解析为 PDF 添加的;而下半部分最后结尾的 “Goodbye!” 是使用document.Add() 指令添加的

接下来一个示例中,我们使用 ConvertToElements() 方法。此方法创建一个 list 的IElement对象。IElement接口由所有iText构建块实现。

For more info about iText's building blocks, please read the iText 7: Building Blocks tutorial.

在这最后一个示例中将List<IElement>/IList集合的每个顶级对象添加到一个Document中,前面有一段显示该对象的名称: Paragraph

public void CreatePdf(string baseUri, string src, string dest)
{
    ConverterProperties properties = new ConverterProperties();
    properties.SetBaseUri(baseUri);
    IList elements = HtmlConverter.ConvertToElements(new FileStream(src, FileMode.Open), properties);
    PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
    Document document = new Document(pdf);
 
    foreach (IElement element in elements)
    {
        document.Add(new Paragraph(element.ToString()));
        document.Add((IBlockElement) element);
    }
 
    document.Close();
}

下图,我们看到该列表由三个元素组成:一个 Div 和两个 Paragraph 对象。

 标头被视为 Div ,而徽标图像包含在 Paragraph 中。不要担心这个;这是iText内部工作的一部分。重要的是最终结果。

总结

在本章中,我们选取了一个非常简单的 HTML 文件,并使用转换方法 ConvertToPdf(),ConvertToDocument() 和 ConvertToElements() ConvertToPdf() ConvertToDocument() 的不同实现将该文件转换为 PDF。当您查阅 HtmlConverter 该类的 API 文档时,您会发现这些方法的更多变体。在下一章中,我们将选择其中一种方法来转换不同的HTML文件。这些 HTML 文件中的每一个都将以不同的方式使用 CSS。