简述PDF原理和实践

server/2024/9/25 23:20:45/

Hello,我是小恒不会java。
由于最近有输出PDF报表的项目需求,所以复习一下PDF到底是什么,该如何产生,如何应用至项目中。
更多参见Adobe官方文档(https://www.adobe.com/cn/)

PDF原理

PDFPortable Document Format,可移植文档格式)是一种用于可靠地呈现和交换文档的标准文件格式。它的设计目标是无论在何种操作系统、硬件配置、字体资源或软件环境下,都能精确地复现原始文档的外观和内容。

为了达到这个效果,我们需要控制每个字符、每个图形的位置。为此Adode的工程师设计了一种语言:PostScript

上经典代码

%PDF-1.1
%¥±ë1 0 obj<< /Type /Catalog/Pages 2 0 R>>
endobj2 0 obj<< /Type /Pages/Kids [3 0 R]/Count 1/MediaBox [0 0 300 144]>>
endobj3 0 obj<<  /Type /Page/Parent 2 0 R/Resources<< /Font<< /F1<< /Type /Font/Subtype /Type1/BaseFont /Times-Roman>>>>>>/Contents 4 0 R>>
endobj4 0 obj<< /Length 55 >>
streamBT/F1 18 Tf0 0 Td(Im liheng) TjET
endstream
endobjxref
0 5
0000000000 65535 f
0000000018 00000 n
0000000077 00000 n
0000000178 00000 n
0000000457 00000 n
trailer<<  /Root 1 0 R/Size 5>>
startxref
565
%%EOF

在这里插入图片描述

%PDF-1.1:PDF文件的版本号,这里是1.1版本。
%¥±ë:PDF文件的二进制标识符,用于区分文本和二进制数据。
1 0 obj:第一个对象,类型为Catalog,包含文档的根对象。
2 0 obj:第二个对象,类型为Pages,包含文档的页面对象。
3 0 obj:第三个对象,类型为Page,包含单个页面的信息。
4 0 obj:第四个对象,类型为Contents,包含页面的内容流。
xref:交叉引用表,列出了PDF文件中每个对象的位置和状态。
trailer:文件尾部,包含文档的根对象和文件大小等信息。
startxref:交叉引用表的起始位置。
%%EOF:PDF文件的结束标记。
PDF文件由多个对象组成,每个对象都有一个唯一的对象编号和生成编号。对象之间通过引用关系连接。在这个示例中,Catalog对象引用了Pages对象,Pages对象引用了Page对象,Page对象引用了Contents对象。Contents对象包含了显示"Hello World"的内容流。
编程形式与页面描述
PDF是一种编程形式的文档格式,其内容通过一系列操作符(operators)进行描述,这些操作符按照特定语法组织,形成一种类似编程语言的指令集。每个PDF文件实质上是一个程序,当被PDF阅读器解析时,它会按照指令重新绘制文档的各个元素,从而在任何支持PDF的系统上一致地呈现文档。

基本结构与显示单元

基本显示单元

文字:文本内容以字符序列的形式存储,附带字体、大小、颜色、位置等属性信息。
图片:包括位图(如JPGPNG)和矢量图形(如线条、形状),以嵌入或链接的方式包含在文件中。
矢量图:使用数学公式描述的图形,可以无限放大而不失真,如线条、曲线、形状等。
页面:PDF文件的基本组织单位,每个页面包含其自身的尺寸、布局、背景、内容流等属性。

扩展单元

元数据:如标题、作者、创建日期等文档元信息。
交互对象:如超链接、按钮、表单域、多媒体内容(音频、视频)、3D模型等,提供了文档的交互功能。
安全特性:如数字签名、权限控制、加密保护等,确保文档的安全性和完整性。
导航元素:如书签、目录、超链接等,帮助用户在文档内快速定位和跳转。
文件结构

PDF文件遵循严格的内部结构,通常包括以下几个部分:

Header:包含PDF版本信息和其他全局设置。

Body:主体部分,由一系列对象(Object)组成,每个对象都有唯一的标识(Object Number和Generation
Number),并按照交叉引用表(Cross-Reference Table)组织,便于随机访问。

Catalog(根对象):指向文档的其他关键部分,如Pages树、Outlines(书签)、Metadata等。

Pages树:描述文档的层级结构,每个页面作为一个单独的对象,包含其内容流(Content Stream)和资源(如字体、图像)引用。

Content Streams:包含前面提到的操作符序列,定义页面上的具体内容绘制指令。

Resources:如字体描述、图像数据等,供内容流引用。

Cross-Reference Table(XREF):列出文件中所有对象的位置信息,使得阅读器能够快速定位到需要的对象。

Trailer:包含XREF表的位置、加密信息(如有)、文件的主目录(Root object)等元数据。 解析与渲染流程

PDF阅读器执行步骤

解析文件头:确认文件为PDF格式并识别其版本。

加载交叉引用表:利用XREF表快速查找文件中对象的位置。

解析对象:按需读取和解析对象(如Catalog、Pages树、Content Streams等),构建文档内部结构的逻辑视图。

渲染页面:对于每个页面,根据其内容流中的操作符序列,逐个绘制文字、图形、图像等元素,应用适当的样式和变换,最终形成可视化的页面图像。

处理交互功能:如果文档包含交互元素,如超链接、表单等,阅读器还需要实现相关的事件响应和用户交互支持。

Java

在Java项目中,有几个流行的库可以用来生成PDF文件,例如iText和Apache PDFBox。
使用iText库:
首先,将iText库添加到项目的依赖中。对于Maven项目,将以下依赖添加到pom.xml文件中:

   <groupId>com.itextpdf</groupId><artifactId>itext7-core</artifactId><version>7.1.16</version>
</dependency>

接下来,使用以下代码创建一个简单的PDF文件:


import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;import java.io.File;
import java.io.IOException;public class PdfExample {public static void main(String[] args) {try {// 创建PdfWriter实例PdfWriter writer = new PdfWriter(new File("hello_world.pdf"));// 创建PdfDocument实例PdfDocument pdf = new PdfDocument(writer);// 创建Document实例Document document = new Document(pdf);// 添加内容document.add(new Paragraph("Hello, World!"));// 关闭文档document.close();} catch (IOException e) {e.printStackTrace();}}
}

Django

在Django项目中,可以使用reportlab库生成PDF文件
接下来,使用以下view.py代码创建一个简单的PDF文件:

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from io import BytesIO
from django.http import FileResponsedef some_view(request):# 创建一个文件类似的缓冲区来接收 PDF 数据buffer = BytesIO()# 创建 Canvas 对象p = canvas.Canvas(buffer, pagesize=letter)# 添加内容p.drawString(100, 750, "Hello, World!")# 关闭 PDF 对象p.showPage()p.save()# 将缓冲区的内容移动到文件响应对象中buffer.seek(0)return FileResponse(buffer, as_attachment=True, filename='hello_world.pdf')

首先创建了一个BytesIO缓冲区来接收PDF数据。创建了一个canvas.Canvas对象,并使用drawString方法添加了一些文本。最后将缓冲区的内容移动到FileResponse对象中,并将其作为响应返回。

具体阅读官方文档,我在此写大致方向,时间太晚了


http://www.ppmy.cn/server/14116.html

相关文章

python制作ppt

在Python中&#xff0c;你可以使用python-pptx库来创建和修改PowerPoint (.pptx) 文件。这个库允许你添加幻灯片、文本框、图片、形状、表格等元素&#xff0c;并可以调整它们的格式和布局。 下面是一个简单的例子&#xff0c;展示了如何使用python-pptx库来创建一个PPT文件&a…

使用 Rust 后,我​​使用 Python 的方式发生了变化

使用 Rust 后&#xff0c;我​​使用 Python 的方式发生了变化 Using type hints where possible, and sticking to the classic “make illegal state unrepresentable” principle. 尽可能使用类型提示&#xff0c;并坚持经典的“使非法状态不可表示”原则。 近年来&#xff…

Java面试八股之经验总结

我们先来聊聊面试的技巧吧&#xff0c;只是单纯的个人经验总结&#xff0c;如果大家觉得有道理&#xff0c;就选择性吸收一下就好了。如果觉得没用&#xff0c;可以直接跳过。 自我介绍一定要好好准备。我之前对自我介绍这部分也不是很重视&#xff0c;面试多了之后我发现&…

深度学习推理框架汇总

深度学习推理框架汇总 TensorFlow Serving&#xff1a;TensorFlow Serving 是 TensorFlow 的官方模型服务框架&#xff0c;专门用于部署 TensorFlow 模型。它提供了高性能、可扩展、灵活的模型部署和推理服务。 TorchServe&#xff1a;TorchServe 是 PyTorch 官方推出的模型服…

2024-4-23 群讨论:Java堆空间OutOfMemoryError该怎么办

以下来自本人拉的一个关于 Java 技术的讨论群。关注公众号&#xff1a;hashcon&#xff0c;私信进群拉你 1. 为什么不建议打开 HeapDumpOnOutOfMemoryError&#xff1f; 1.1. 打开 HeapDumpOnOutOfMemoryError&#xff0c;哪些 OutOfMemoryError 会触发 HeapDumpOnOutOfMemory…

数据库服务的运行与登录

打开数据库服务 数据库服务: SQL Server(MSSQLServer) 运行在服务器端的应用程序, 提供数据的存储 / 处理和事务等在使用DBMS的客户端之前必须首先打开该服务 客户端连接到服务器 关于客户端 / 服务器端的说明 客户端 : 数据库管理系统(DBMS), 应用程序服务器端 : 安装的数据…

期权小知识科普

期权的交易时间 上交所期权合约的交易时间为每个交易日9:15至9:25、9:30至11:30、13&#xff1a;00至15:00。 其中&#xff0c;9:15至9:25为开盘集合竞价时间&#xff0c;14:57-15:00为收盘集合竞价时间&#xff0c;其余时段为连续竞价时间&#xff0c;交易所规则另有规定的除…

Day1--什么是网络安全?网络安全常用术语

目录 1. 什么是网络安全&#xff1f; 信息系统&#xff08;Information System&#xff09; 信息系统安全三要素&#xff08;CIA&#xff09; 网络空间安全管理流程 网络安全管理 2. 网络安全的常用术语 3. 网络安全形势 4. 中国网络安全产业现状 1. 什么是网络安全&am…