iText7高级教程之html2pdf——1.从Hello HTML开始

Posted CuteXiaoKe

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iText7高级教程之html2pdf——1.从Hello HTML开始相关的知识,希望对你有一定的参考价值。

  在本章,我们通过不同的方法把一个简单的html文件转换为PDF文件。HTML文件的内容包含一个"TEST"标题,一个"Hello world"段落和一张iText logo图片。

1. 本教程样例文件的格式

  在本教程的的所有样例都有类似的结构。

1.1 输入:

  对于HTML文件的输入,我们有多种方式,例如使用一个是HTML语义的String,或者指向HTML文件的路径,或者在第4章中指向一个XML文件的路径和指向一个XSLT文件的路径(这两个文件同时用于把XML文件转换为HTML文件)。

  在接下来的第一个例子中,HTML的输入来源于一个String:

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

  在其他例子中,我们会使用两个变量:

  • BASEURI变量,是一个父目录,这个目录里面包含HTML文件和这个HTML文件所需的资源文件,例如图像、视频、CSS、JS等;
  • SRC变量,指向HTML文件的路径;

  举个栗子:

public static String BASEURI = "src/main/resources/html/";
public static String SRC = String.format("%shello.html", BASEURI)

1.2 输出:

  输出也是类似的:

  • TATGET变量,代表着我们将要写入结果文件的目录;
  • DEST变量,结果文件的真实路径;

  举个栗子:

public static String TARGET = "target/results/ch01/";
public static String DEST = String.format("%stest-03.pdf", TARGET);

1.3 主方法:

  在本教程的所有主方法中,都是与以下的类似:

public static void main(String[] args) throws IOException 
   LicenseKey.loadLicenseFile(
      System.getenv("ITEXT7_LICENSEKEY") + "/itextkey-html2pdf_typography.xml");
   File file = new File(TARGET);
   file.mkdirs();
   new C01E01_HelloWorld().createPdf(HTML, DEST);

  首先,我们会载入Text的许可证文件,这个一个可以使用iText的注册码,当然如果在一个项目中遵循了APGL协议并使用iText和pdfHTML,那么你就不要这个引入这个注册码文件,去掉这一行即可。但是,在第6章我们在国际化打的时候需要使用pdfCalligraph插件,就需要这个许可证了,因为这个插件不在APGL许可协议下,它是闭源的插件。

如果你买了iText的商业许可证,那么你会发现它的内容和注册码里面的内容是类似的

  然后我们生成目标文件的时候,如果目标目录不存在的话会创建相应的目录。让我们聚焦于createPdf()/CreatePdf()方法,并使用不同的方式来实现这些方法。

2. HTML转换为PDF

  如下实现createPdf()/CreatePdf()接口的代码十分简单,只有一行:

public void createPdf(String html, String dest) throws IOException 
    HtmlConverter.convertToPdf(html, new FileOutputStream(dest));

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

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

  HTML片段转换为PDF文件的效果如图1.1所示:

图1.1 转换HTML片段为PDF

  让我们引入一个图像,并使用以下string

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

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

  这是使用ConverterProperties 对象完成的,新的实现代码如下:

public void createPdf(String baseUri, String html, String dest) throws IOException 
    ConverterProperties properties = new ConverterProperties();
    properties.setBaseUri(baseUri);
    HtmlConverter.convertToPdf(html, new FileOutputStream(dest), properties);

  结果如图1.2所示

图1.2 转换包含对图像的引用的 HTML 片段

  在接下来的大多数示例中,我们不会使用存储在String中的 HTML。 相反,我们将把磁盘上的 HTML 文件转换成磁盘上的文件。

  对于本章的其余示例,我们将使用如图 1.3 所示的名为hello.html的文件。

图1.3 hello.html 显示在浏览器和文本编辑器中

  有很多种方法可以把这个文件转换为PDF文档。

  首先请我们使用File / FileInfo对象,如下:

public void createPdf(String baseUri, String src, String dest) throws IOException 
    HtmlConverter.convertToPdf(new File(src), new File(dest));

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

  但是这不适用于第4个示例,其中我们使用FileInputStream/FileStreamFileOutputStream/FileStream对象而不是File/FileInfo对象:

public void createPdf(String baseUri, String src, String dest) throws IOException 
    ConverterProperties properties = new ConverterProperties();
    properties.setBaseUri(baseUri);
    HtmlConverter.convertToPdf(
        new FileInputStream(src), new FileOutputStream(dest), properties);

  您无法在此处检索父级,因此我们需要使用ConverterProperties实例将基本URI传递给转换器。 第三和第四个示例的结果 PDF 看起来与图 1.2所示的第二个示例的结果 PDF 相同。 第五个示例生成 PDF 也是如此:

public void createPdf(String baseUri, String src, String dest) throws IOException  
    ConverterProperties properties = new ConverterProperties();
    properties.setBaseUri(baseUri);
    PdfWriter writer = new PdfWriter(dest,
        new WriterProperties().setFullCompressionMode(true));
    HtmlConverter.convertToPdf(new FileInputStream(src), writer, properties);

  在这种情况下,我们使用PdfWriter实例而不是FileOutputStream/FileStream。 如果要设置某些writer属性,使用PdfWriter会很有用。

  有关 writer 属性的更多信息,请阅读iText7高级教程之构建基础块——7.处理事件,设置阅读器首选项和打印属性

  在此示例中,我们以完全压缩模式创建 PDF。 在人眼看来,生成的 PDF 看起来是一样的,但是当您将示例 4 中生成的 PDF 的文件大小与本示例中生成的 PDF 的文件大小进行比较时,您会发现完全压缩为我们节约了少量字节。

  如图 1.4显示了使用PDF1.0到PDF1.4(itext5默认1.4,itext7默认1.7)中所做的压缩时的 3,430 字节; 而当使用 PDF 1.5 中介绍的压缩时,该文件仅计算 3,263 个字节。 这种差异可能看起来很小,但PDF拥有的对象越多,使用完全压缩就越有意义。

图1.4 比较文件大小

  在第6个例子中,我们将PdfWriter 参数替换为PdfDocument参数。

public void createPdf(String baseUri, String src, String dest) throws IOException  
    ConverterProperties properties = new ConverterProperties();
    properties.setBaseUri(baseUri);
    PdfWriter writer = new PdfWriter(dest);
    PdfDocument pdf = new PdfDocument(writer);
    pdf.setTagged();
    HtmlConverter.convertToPdf(new FileInputStream(src), pdf, properties);

  如果您想在PdfDocument级别配置功能,则使用PdfDocument实例是有意义的。 在这种情况下,我们引入了 pdf.setTagged()/pdf.SetTagged()行,它指示iText创建一个带有标签的PDF(Tagged PDF)。

  如图 1.5显示了打开标签面板的结果 PDF。

图1.5 创建带有标记的PDF

  查看标签面板,您可以看到内容的结构。 将鼠标悬停在图像上时,您会看到<img>标记的alt属性值作为悬浮提示。

  有关 Tagged PDF 的更多信息,请阅读itext7学习笔记——第7章

  我们将在第 3 章深入探讨带标签的 PDF,并使 PDF 变得“可阅读(accessible)”

3. HTML转换为iText对象

  convertToPdf()/ConvertToPdf()方法创建一个完整的 PDF 文件。 一旦输入被解析并转换为 PDF,传递给 convertToPdf()/ConvertToPdf()方法的任何FileFileInfoOutputStreamPdfWriterPdfDocument 都会关闭。 这可能并不总是您想要的。

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

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

public void createPdf(String baseUri, String src, String dest) throws IOException  
    ConverterProperties properties = new ConverterProperties();
    properties.setBaseUri(baseUri);
    PdfWriter writer = new PdfWriter(dest);
    PdfDocument pdf = new PdfDocument(writer);
    Document document =
        HtmlConverter.convertToDocument(new FileInputStream(src), pdf, properties);
    document.add(new Paragraph("Goodbye!"));
    document.close();

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

图1.6 使用convertToDocument()方法

  图1.6的上半部分内容是通过将HTML解析为PDF添加的; 下半部分——“Goodbye!!” 是在最后使用 document.add()/document.Add()指令添加。

  在本章最后一个实例中,我们使用convertToElements()/ConvertToElements()方法。 此方法创建一个元素为IElementListIElement接口由所有iText 构建块实现,详情请参考Text7高级教程之构建基础块

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

public void createPdf(String baseUri, String src, String dest) throws IOException  
    ConverterProperties properties = new ConverterProperties();
    properties.setBaseUri(baseUri);
    List<IElement> elements =
        HtmlConverter.convertToElements(new FileInputStream(src), properties);
    PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
    Document document = new Document(pdf);
    for (IElement element : elements) 
        document.add(new Paragraph(element.getClass().getName()));
        document.add((IBlockElement)element);
    
    document.close();

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

图1.7 一次添加一个元素

  头部被视为Div,而iText徽标图像被包裹在Paragraph中。 不用担心困惑这个; 这是 iText 内部工作的原理。 重要的是最终结果。

4. 总结

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

以上是关于iText7高级教程之html2pdf——1.从Hello HTML开始的主要内容,如果未能解决你的问题,请参考以下文章

iText7高级教程之html2pdf——0.引言

iText7高级教程之html2pdf——2.使用CSS定义样式

iText7高级教程之html2pdf——2.使用CSS定义样式

iText7高级教程之html2pdf——2.使用CSS定义样式

iText7高级教程之html2pdf——3.基于媒体查询生成PDF

iText7高级教程之html2pdf——3.基于媒体查询生成PDF