PDF(Portable Document Format)是一种广泛使用的文档格式,由 Adobe 公司开发。了解 PDF 的基础数据结构对于深入理解 PDF 文件格式和进行 PDF 处理非常重要。本文将详细介绍 PDF 文件中的基本数据结构。
目录
- [1. PDF 文件的基本结构](#1. PDF 文件的基本结构 "#1-pdf-%E6%96%87%E4%BB%B6%E7%9A%84%E5%9F%BA%E6%9C%AC%E7%BB%93%E6%9E%84")
- [1.1 文件头(Header)](#1.1 文件头(Header) "#11-%E6%96%87%E4%BB%B6%E5%A4%B4header")
- [1.2 文件体(Body)](#1.2 文件体(Body) "#12-%E6%96%87%E4%BB%B6%E4%BD%93body")
- [1.3 交叉引用表(Cross-reference Table)](#1.3 交叉引用表(Cross-reference Table) "#13-%E4%BA%A4%E5%8F%89%E5%BC%95%E7%94%A8%E8%A1%A8cross-reference-table")
- [1.4 文件尾(Trailer)](#1.4 文件尾(Trailer) "#14-%E6%96%87%E4%BB%B6%E5%B0%BEtrailer")
- [1.5 完整示例](#1.5 完整示例 "#15-%E5%AE%8C%E6%95%B4%E7%A4%BA%E4%BE%8B")
- [2. PDF 基本数据类型](#2. PDF 基本数据类型 "#2-pdf-%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B")
- [2.1 布尔值(Boolean)](#2.1 布尔值(Boolean) "#21-%E5%B8%83%E5%B0%94%E5%80%BCboolean")
- [2.2 数字(Number)](#2.2 数字(Number) "#22-%E6%95%B0%E5%AD%97number")
- [2.3 字符串(String)](#2.3 字符串(String) "#23-%E5%AD%97%E7%AC%A6%E4%B8%B2string")
- [2.4 名称(Name)](#2.4 名称(Name) "#24-%E5%90%8D%E7%A7%B0name")
- [2.5 数组(Array)](#2.5 数组(Array) "#25-%E6%95%B0%E7%BB%84array")
- [2.6 字典(Dictionary)](#2.6 字典(Dictionary) "#26-%E5%AD%97%E5%85%B8dictionary")
- [2.7 流(Stream)](#2.7 流(Stream) "#27-%E6%B5%81stream")
- [3. PDF 对象引用](#3. PDF 对象引用 "#3-pdf-%E5%AF%B9%E8%B1%A1%E5%BC%95%E7%94%A8")
- [4. 常用 PDF 对象类型](#4. 常用 PDF 对象类型 "#4-%E5%B8%B8%E7%94%A8-pdf-%E5%AF%B9%E8%B1%A1%E7%B1%BB%E5%9E%8B")
- [4.1 页面对象(Page)](#4.1 页面对象(Page) "#41-%E9%A1%B5%E9%9D%A2%E5%AF%B9%E8%B1%A1page")
- [4.2 内容流(Content Stream)](#4.2 内容流(Content Stream) "#42-%E5%86%85%E5%AE%B9%E6%B5%81content-stream")
- [4.3 字体对象(Font)](#4.3 字体对象(Font) "#43-%E5%AD%97%E4%BD%93%E5%AF%B9%E8%B1%A1font")
- [4.4 图像对象(Image)](#4.4 图像对象(Image) "#44-%E5%9B%BE%E5%83%8F%E5%AF%B9%E8%B1%A1image")
1. PDF 文件的基本结构
PDF 文件由以下几个主要部分组成,每个部分都有其特定的功能和格式。
1.1 文件头(Header)
文件头是 PDF 文件的开始部分,包含版本信息和标识符。
pdf
%PDF-1.7
%¥±ë
💡 说明:
- 第一行
%PDF-1.7
指定 PDF 版本为 1.7- 第二行
%¥±ë
是二进制注释,用于标识文件为 PDF 格式
1.2 文件体(Body)
文件体包含文档的所有内容,由一系列对象组成。
pdf
1 0 obj
<<
/Type /Catalog
/Pages 2 0 R
>>
endobj
2 0 obj
<<
/Type /Pages
/Kids [3 0 R]
/Count 1
>>
endobj
📝 要点:
- 每个对象都有唯一的编号和生成号
- 对象之间通过引用相互关联
- 对象可以是字典、数组、流等类型
1.3 交叉引用表(Cross-reference Table)
交叉引用表记录所有对象的位置,用于快速定位对象。
pdf
xref
0 6
0000000000 65535 f
0000000010 00000 n
0000000056 00000 n
0000000112 00000 n
0000000204 00000 n
0000000256 00000 n
🔍 解析:
- 第一行
0 6
表示从对象 0 开始,共 6 个条目- 每行包含:
- 对象在文件中的偏移量(10位数字)
- 生成号(5位数字)
- 状态标记(n 表示使用中,f 表示空闲)
- 例如
0000000010 00000 n
表示对象 1 在文件偏移量 10 处
1.4 文件尾(Trailer)
文件尾包含文档的根对象引用和文件结束标记。
pdf
trailer
<<
/Size 6
/Root 1 0 R
>>
startxref
320
%%EOF
📌 关键字段:
/Size
指定交叉引用表中的条目数/Root
指向文档的根对象(通常是目录对象)startxref
指定交叉引用表的起始位置%%EOF
是文件结束标记
1.5 完整示例
下面是一个完整的 PDF 文件结构示例:
pdf
%PDF-1.7
%¥±ë
1 0 obj
<<
/Type /Catalog
/Pages 2 0 R
>>
endobj
2 0 obj
<<
/Type /Pages
/Kids [3 0 R]
/Count 1
>>
endobj
3 0 obj
<<
/Type /Page
/Parent 2 0 R
/Resources <<
/Font <<
/F1 4 0 R
>>
>>
/Contents 5 0 R
/MediaBox [0 0 595 842]
>>
endobj
4 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
>>
endobj
5 0 obj
<<
/Length 100
>>
stream
BT
/F1 12 Tf
100 700 Td
(Hello World) Tj
ET
endstream
endobj
xref
0 6
0000000000 65535 f
0000000010 00000 n
0000000056 00000 n
0000000112 00000 n
0000000204 00000 n
0000000256 00000 n
trailer
<<
/Size 6
/Root 1 0 R
>>
startxref
320
%%EOF
🌟 示例说明: 这个示例展示了一个简单的 PDF 文件结构:
- 文件头声明 PDF 版本
- 文件体包含 5 个对象:
- 目录对象(Catalog)
- 页面树对象(Pages)
- 页面对象(Page)
- 字体对象(Font)
- 内容流对象(Content Stream)
- 交叉引用表记录所有对象的位置
- 文件尾包含文档的根对象引用和交叉引用表位置
2. PDF 基本数据类型
PDF 支持多种基本数据类型,每种类型都有其特定的语法和用途。
2.1 布尔值(Boolean)
布尔值表示真或假。
pdf
/NeedAppearances true
2.2 数字(Number)
数字可以是整数或实数。
pdf
/Width 595.28
2.3 字符串(String)
字符串用括号括起来,支持转义字符。
pdf
(Hello World)
(Hello\nWorld) # 包含换行符
2.4 名称(Name)
名称以 /
开头,用于标识对象。
pdf
/Type /Font
/#20#20 # 表示两个空格
2.5 数组(Array)
数组用方括号括起来,可以包含不同类型的元素。
pdf
[1 2 3]
[1 (text) /Name] # 混合类型数组
2.6 字典(Dictionary)
字典用双尖括号括起来,包含键值对。
pdf
<<
/Type /Page
/Parent 2 0 R
/Resources <<
/Font <<
/F1 3 0 R
>>
>>
/MediaBox [0 0 595 842]
>>
2.7 流(Stream)
流包含二进制数据,通常用于存储图像、字体等。
pdf
<<
/Length 100
/Filter /FlateDecode
>>
stream
...二进制数据...
endstream
3. PDF 对象引用
PDF 使用对象引用来建立对象之间的关系。
pdf
1 0 obj
<<
/Type /Catalog
/Pages 2 0 R
>>
endobj
2 0 obj
<<
/Type /Pages
/Kids [3 0 R]
/Count 1
>>
endobj
📝 格式说明:
- 格式:
对象编号 生成号 R
- 示例:
2 0 R
表示编号为 2,生成号为 0 的对象
4. 常用 PDF 对象类型
4.1 页面对象(Page)
页面对象定义页面的内容和属性。
pdf
3 0 obj
<<
/Type /Page
/Parent 2 0 R
/Resources <<
/Font <<
/F1 4 0 R
>>
>>
/Contents 5 0 R
/MediaBox [0 0 595 842]
>>
endobj
4.2 内容流(Content Stream)
内容流包含页面的实际内容。
pdf
5 0 obj
<<
/Length 100
>>
stream
BT
/F1 12 Tf
100 700 Td
(Hello World) Tj
ET
endstream
endobj
4.3 字体对象(Font)
字体对象定义文本使用的字体。
pdf
4 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
>>
endobj
4.4 图像对象(Image)
图像对象存储图像数据。
pdf
6 0 obj
<<
/Type /XObject
/Subtype /Image
/Width 100
/Height 100
/ColorSpace /DeviceRGB
/BitsPerComponent 8
/Filter /DCTDecode
>>
stream
...JPEG 图像数据...
endstream
endobj