必要工作:
1)下载国际开源组织apache旗下顶级项目pdfbox的最新版本,目前为1.6.0;
2)下载国际开源组织apache旗下顶级项目logging的java版本。
使用pdfbox创建一个全新的pdf文件:
首先将所有相关的jar包导入任意ide环境的环境中,作者使用的Intellij IDEA 10.5
在此作者创建一个名为BlankPDFDocumentCreator的类来演示怎样使用pdfbox创建一个包含一个空白页面的pdf文档,如下:
import org.apache.pdfbox.exceptions.COSVisitorException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import java.io.IOException; public class BlankPDFDocumentCreator { public void createBlankPdfDocument(String outFile) throws IOException, COSVisitorException { //PDDocument是pdf文档在内存的表示 PDDocument document = new PDDocument(); // PDPage 表示pdf文档中的一个 PDPage pdPage = new PDPage(); //将新创建的PDPage增加到document也就是增加一个页面到泡打粉文档中 document.addPage(pdPage); //保存创建的pdf文档 document.save(outFile); } public static void main(String [] args) throws IOException,COSVisitorException { BlankPDFDocumentCreator creator = new BlankPDFDocumentCreator(); if(args.length == 1) { creator.createBlankPdfDocument(args[0]); } else { creator.createBlankPdfDocument("d:\\blank.pdf"); } } }
以上简单的代码就可以创建一个包含一个空白页面的pdf文档如下图,从此处可以看出使用pdfbox操作pdf文档是很方便的创建这个空白pdf文档时发生了什么,我们下面就来看一看有什么神奇的地方。用ultraedit打开这个空白pdf文档。如下如所示图 2 空白pdf文档在文件中的内容一切尽在眼前,一览无遗,一个空白pdf文档在文件中就是如此,跟一个普通的文本文件没有多大区别,但是pdf文档却不是文本文件,在此是比较特殊的,因为文件中没有可用的有意义的内容,才表现的是一个文本文件,文件中的各个部分都是什么意思呢,下面我们就一一探究。这时我们需要一个秘密武器出场了,究极武器之Adobe® Portable Document Format Reference,这里我们使用的是第六版,各位看官有兴趣可以看一看,这是一本一千多页的英文文档,呵呵,估计没有几个人回去看,不过希望各位看一看,很有益处的不是想象中那么难(作者本人至今四级为过)。首先介绍一个pdf问当的文件结构,文件结构规定pdf文档包含的内容怎么存储在文件中。看下图:在pdf 参考1.7版本中低90页给出上图内容,如上图所示,一个pdf文档的文件结构由 Header、Body、Cross-reference table、Trailer四个部分组成,与图2中的各个部分有什么关系呢。
Header:指明这个pdf文档符合哪个版本的pdf规范,如图2所示我们使用pdfbox创建的文档符合1.4版本的pdf规范。Body: 包含组成文档的各种内容(文本、图片等...)的pdf内部表示,pdf规范制定了一系列的对象来表示各种内容。以后我们将一一介绍。Aross-reference table:包含文档中各种间接对象的信息,间接对象是指具有对象标示的对象,间接对象可以被其他对象引用,Aross-reference table的作用就是给出这些可引用对象的信息,间接对象可以随机访问,Aross-reference table的每一项都有三个部分组成:
nnnnnnnnnn ggggg n/f第一部分是十进制的偏移,他表示间接对象在文件中的偏移(绝对偏移),第二部分表示产生号,意思是该项从被创建到目前被修改的次数,第三部分表示该间接对象是否还在使用n表示使用中,f表示没有使用,每一项制定的对象是与Body中出现的对象的顺序相关的。第一项表示第一个出现的对象trailer: 该部分是pdf文档最终要的部分,是软件操作pdf文档的入口,它记录pdf文档的根对象的对象标识,和Aross-reference table在文件中的起始位置。通常是这里找到文件中的其他对象,
下面我们来解释一下图2中出现的各个部分:
首先看一下trailer部分
//Root 1 0 R 标识跟对象是对象标识为1的对象,也就是第三行开始的那个对象,R标识该项应用对象1标识的对象。
//ID [<30C377FAE4150E97A75D0CA977F56FD8> <30C377FAE4150E97A75D0CA977F56FD8>] 用于标识文档
//Size 4 标识交叉引用表的项的个数这里为4
startxref 206 表示交叉引用表在文件中的位置,%%EOF标识文件结束。
Aross-reference table部分,该部分有xref开始知道trailer结束,xref标识交叉引用表开始。0标识对象标识从0开始, 4 表示有多少项,第一项是标识header部分,
0 4
0000000000 65535 f
0000000015 00000 n
0000000078 00000 n
0000000135 00000 n
Body部分,这里主要是3-23行,记录了3个对象,第一个对象的标识1,回头看看在trailer部分的/Root是指pdf文档的跟对象他引用对象标识为1的对象,
1 0 obj 1标识对象标识,0标识产生号,obj表示一个对象内容的起始
<<
/Type /Catalog //Type 表示对象类型 //Catalog 标识该对象的类型名称,这里为大纲对象(后续文章将会介绍)
/Version /1.4 指明该文档的符合的pdf文档规范,这里为1.4
/Pages 2 0 R 这里指明pdf文档中的page集合对象,这里标识对象标识为2的对象是页集合对象,
>>
endobj 对象结束
2 0 obj
<<
/Type /Pages 页集合对象,一个页集合对象包含对个页面对象
/Kids [3 0 R] 表示页集合对象包含的也对象这里只有包含一个对象,也即是我们创建的那个页面
/Count 1 标识有多少个页面
>>
endobj
3 0 obj
<<
/Type /Page 页面对象
/MediaBox [0 0 612 792] 页面大小
/Parent 2 0 R 父对象,既是页集合对象
>>
endobj
申明:
本文章为个人原创任何个人和组织可以自由传播,但禁止用于任何商业用途!
参考:pdf reference version 1.7