位于上海,服务全国!

位于上海,服务全国!

助力您的企业早日腾飞!

助力您的企业早日腾飞!

专业,专注的网络技术!

专业,专注的网络技术!

携手走向远方!

携手走向远方!

如何通过java程序使用iText创建一个PDF文档

作者:admin 分类: 时间:2018-02-06 20:53:33 点击量:134

 

 

便携式文档格式,即PDF格式,是标准的用户交换文档。java程序员有时需要创建文件的应用程序数据以展示商家信息或创建可交换或无干扰的数据布局和格式的报告。PDF是一种理想的文件格式,其不受软件硬件和操作系统的限制。本文深入探讨一款被称为iText的工具,其可助力java程序员通过java代码创建PDF文件。
概述
便携文档格式(PDF)是部分Camelot项目,由Adobe系统公司创始人John Edward Warnock博士,1991年开发出的产品。目标是使任何人能够从任何应用程序获取所交换的电子版本文档。它经受住了时间的考验,成为多年来电子文档交换的一种可信格式。
虽然PDF现在是一个开放的文件格式(ISO-32000-1)由国际标准化组织(ISO)维护,但一些运行而不可或缺的组成部分仍然属于Adobe的专利权范围(如Adobe XML形式结构和Adobe的JavaScript)。PDF文档可以包含各种元素,而不仅仅是文本,如链接和按钮、表单字段、音频、视频和业务逻辑。它也可以用电子签名,而且很容易通过阅读器(Adobe PDF阅读器应用程序)读出。然而,现今还有许多其他的开源PDF应用程序,可以用来创建、读取和写入PDF文件格式。流行的微软Office和LibreOffice可以进行这种格式文件的输出。
iText是一个java库,其可使开发人员能够通过java代码生成和操纵PDF文件。该库提供了一些强大的功能来生成只读的、与平台无关的文档,这些文档不仅包含文本,而且还包含列表、表和图像。这个库对于创建外观感觉一致的文档特别有用;然而, java做得最好的是创建一个基于浏览器的HTML网页。这个API很方便,而且很容易学习。iText有一个基于.NET框架的版本。运行iText库需要java版本5或以上。

Maven依赖关系: pom.xml
这是一个需要添加到pom.xml文件的依赖,进而可以运行以下示例。行注释<!-开始>和<!-结束>是必要的;其他显示的标记和依赖是可选项。

<project xmlns="http://maven.apache.org/POM/4.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
      http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.mano.examples</groupId>
   <artifactId>itextexamples</artifactId>
   <version>1.0-SNAPSHOT</version>
   <packaging>jar</packaging>
   <name>itextexamples</name>
   <url>http://maven.apache.org</url>
   <properties>
      <project.build.sourceEncoding>UTF-8
         </project.build.sourceEncoding>
   </properties>
   <build>
      <plugins>
         <plugin>
            <groupId>
               org.apache.maven.plugins
            </groupId>
            <artifactId>
               maven-compiler-plugin
            </artifactId>
            <version>3.7.0</version>
            <configuration>
               <source>1.8</source>
               <target>1.8</target>
            </configuration>
         </plugin>
      </plugins>
   </build>
   <dependencies>
      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>3.8.1</version>
         <scope>test</scope>
      </dependency>

<!-- START -->

      <!-- add all iText 7 Community modules -->
      <dependency>
         <groupId>com.itextpdf</groupId>
         <artifactId>itext7-core</artifactId>
         <version>7.1.0</version>
         <type>pom</type>
      </dependency>
      <!-- https://mvnrepository.com/artifact/org.slf4j/
         slf4j-api -->
      <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>slf4j-api</artifactId>
         <version>1.7.25</version>
      </dependency>
      <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>slf4j-jdk14</artifactId>
         <version>1.7.25</version>
      </dependency>
<!-- END -->

   </dependencies>
</project>

运行PDF文档
直观地说,一个PDF文件是一个多文档容器,而iText文档类是默认的根元素。它提供了页面大小设置、页面旋转、添加元素和根据特定坐标编写文本的方法。因为这个类不知道实际的PDF格式和语法,而库提供文档子类,称为pdfdocument类。这个类实例提供了与PDF文档一起工作的入口点。
这个类提供了与PDF文档一起运行的必要功能,如添加页面、字体、和事件;从一个文档复制页面到另一个;提取文档的信息;等等。打开一个PDF文档以便于写入,它必须被打开,且与一个pdfwriter实例关联。以类似的方式,一个PDF文档被打开阅读和分析时,必须和PDFreader实例关联打开。pdfwriter订阅的java核心类java.io.outputstream和PDFreader对java.io.inputstream。他们都在包命名的com.itextpdf.kernel.pdf被定义。而PDFreader提供了五个构造函数,如:

PdfReader (File file)
PdfReader (InputStream is)
PdfReader (InputStream is, ReaderProperties prop)
PdfReader (IRandomAccessSource byteSource, ReaderProperties prop)
PdfReader (String fileName)
PdfReader (String fileName, ReaderProperties prop)
And, the constructors of PdfWriter are the following:

PdfWriter (java.io.File file)
PdfWriter (java.io.OutputStream ostream)
PdfWriter (java.io.OutputStream ostream, com.itextpdf.kernel.pdf.WriterProperties props)
PdfWriter (java.lang.String fileName)
PdfWriter (java.lang.String fileName, com.itextpdf.kernel.pdf.WriterProperties props)

任何一个此类构造函数都可以被用于创建pdfwriter / PDFreader实例。该库提供了一些必要功能,以便根据PDF文档的规则读取和写入字节信息。
一个简单的例子
这是一个非常简单和基本的例子,以便于说明前面讨论的构思。代码是不言自明的。iText 7 API文档可以在这个链接中被找到。

package org.mano.examples;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.*;
import javax.swing.text.StyleConstants;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class PdfReportSample {
   private OutputStream fos;
   private PdfWriter writer;
   private PdfDocument pdfdoc;
   private Document doc;
   private String filename;

   public PdfReportSample(String filename)
         throws IOException{
      this.filename=filename;
      fos = new FileOutputStream(new File(filename));
      writer = new PdfWriter(fos);
      pdfdoc = new PdfDocument(writer);
      doc = new Document(pdfdoc);
      createSimpleTextReport();
      doc.close();
      writer.close();
   }

   private void createSimpleTextReport(){
      doc.add(new Paragraph("Available Processors: "
         + Runtime.getRuntime().availableProcessors()
         + " Cores"));
      doc.add(new Paragraph("Free Memory :"
         + Runtime.getRuntime().freeMemory() + " bytes"));
      doc.add(new Paragraph("Maximum Memory used
         by JVM :"
         + Runtime.getRuntime().maxMemory() + " bytes"));
      doc.add(new Paragraph("Total Memory available :"
         + Runtime.getRuntime().totalMemory() + " bytes"));
      doc.add(new Paragraph("File System Roots"));
      File roots[] = File.listRoots();
      List list = new List();
      for (File root : roots) {
         list.add(new ListItem("File system root: "
            + root.getAbsolutePath()))
            .add(new ListItem("Total space: "
               + root.getTotalSpace() + " bytes"))
            .add(new ListItem("Free space: "
               + root.getFreeSpace() + " bytes"))
            .add(new ListItem("Usable space: "
               + root.getUsableSpace() + " bytes"));
         doc.add(list);
      }
   }
}

前面的数据也可以用表格形式来描述,且如下所示。为了使代码更易于理解,已尽量详尽的编写代码。

private void createTabularReport(){
   Table table=new Table(3);
   table.addHeaderCell(new Cell().add(new
      Paragraph("Caption")));
   table.addHeaderCell(new Cell().add(new
      Paragraph("Value")));
   table.addHeaderCell(new Cell().add(new
      Paragraph("Unit")));
   table.addCell(new Cell().add(new
      Paragraph("Available Processors")));
   table.addCell(new Cell().add(new
      Paragraph(String.valueOf(Runtime.getRuntime()
      .availableProcessors()))));
   table.addCell(new Cell().add(new
      Paragraph("")));
   table.addCell(new Cell().add(new
      Paragraph("Free Memory")));
   table.addCell(new Cell().add(new
      Paragraph(String.valueOf(Runtime.getRuntime()
      .freeMemory()))));
   table.addCell(new Cell().add(new
      Paragraph("bytes")));
   table.addCell(new Cell().add(new
      Paragraph("Maximum Memory")));
   table.addCell(new Cell().add(new
      Paragraph(String.valueOf(Runtime.getRuntime()
      .maxMemory()))));
   table.addCell(new Cell().add(new
      Paragraph("bytes")));
   File roots[] = File.listRoots();
   for (File root : roots) {
      table.addCell(new Cell().add(new
         Paragraph("File System root")));
      table.addCell(new Cell().add(new
         Paragraph(root.getAbsolutePath())));
      table.addCell(new Cell().add(new
         Paragraph("bytes")));
      table.addCell(new Cell().add(new
         Paragraph("Total space")));
      table.addCell(new Cell().add(new Paragraph(
         String.valueOf(root.getTotalSpace()))));
      table.addCell(new Cell().add(new
         Paragraph("bytes")));
      table.addCell(new Cell().add(new
         Paragraph("Free space")));
      table.addCell(new Cell().add(new Paragraph(
         String.valueOf(root.getFreeSpace()))));
      table.addCell(new Cell().add(new
      Paragraph("bytes")));
      table.addCell(new Cell().add(new
         Paragraph("Usable space")));
      table.addCell(new Cell().add(new Paragraph(
         String.valueOf(root.getUsableSpace()))));
      table.addCell(new Cell().add(new
         Paragraph("bytes")));
   }
   doc.add(table);
}

供于java程序员的iText库
也许这个库最重要的特征是我们能够通过其创建PDF文档,而不需要知道PDF规范的复杂性。该规范巨大而复杂,因为它包含除文本外更多的功能,如交叉引用表、图形、链接、文件附件,丰富的媒体,等等。然而,该库在其支持方面是有限的,但仍然提供了以编程方式创建PDF文档的基本特性。这个API直观易学。在大多数情况下,开发人员不需要创建复杂的PDF文档。但是,随着库的发展,规范缺失的地方将会被弥补。

结论
在iText的开发者主页提供了很多库的各种功能举例。有许多类可用来处理PDF格式的其他事项。这篇文章只是简单地介绍一下库的内容。