简述PDF原理和实践

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.mzph.cn/news/824479.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习实验二-----决策树构建

决策树是机器学习中一种基本的分类和回归算法&#xff0c;是依托于策略抉择而建立起来的树。本文学习的是决策树的分类 1. 构建决策树流程 选择算法&#xff1a;常用的算法包括ID3、C4.5、CART等。 划分节点&#xff1a;根据数据特征和算法选择&#xff0c;递归地划分节点&…

亚信安全数据安全运营平台DSOP新版本发布 注入AI研判升维

在当今快速发展的数字经济时代&#xff0c;企业对于数据的依赖日益加深&#xff0c;数据安全已成为企业的生命线。亚信安全推出数据安全运营平台DSOP全新版本&#xff0c;正是为满足企业对数据安全的高度需求而设计。这款平台以其卓越的能力和技术优势&#xff0c;为企业的数据…

漂亮的七彩引导页导航HTML源码

源码介绍 漂亮的七彩引导页导航HTML源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c;重定向这个界面 效果截图 源码下载 漂亮的七彩…

notepad++安装包(亲测可用)

目录 一、软件简介 二、软件下载 一、软件简介 Notepad是一款开源的、免费的文本编辑器&#xff0c;它最初由侯今吾基于Scintilla文本编辑组件独立研发。Notepad以GPL发布&#xff0c;并拥有完整的中文化接口&#xff0c;支持多国语言编写的功能&#xff08;采用UTF8技术&…

初始Next.js

版本&#xff1a; 本系列next.js基于的是目前最新版本的 v14 版本&#xff0c;需要 Node.js 18.17 及以后版本 创建项目&#xff1a; 最快捷的创建 Next.js 项目的方式是使用 create-next-app脚手架&#xff0c;你只需要运行&#xff1a; npx create-next-applatest&&am…

【C++题解】1565. 成绩(score)

问题&#xff1a;1565. 成绩&#xff08;score&#xff09; 类型&#xff1a;基本运算、小数运算 题目描述&#xff1a; 牛牛最近学习了 C 入门课程&#xff0c;这门课程的总成绩计算方法是&#xff1a; 总成绩作业成绩 20% 小测成绩 30% 期末考试成绩 50%。 牛牛想知道&am…

04-15 周一 GitHub仓库CI服务器actions-runner和workflow yaml配置文档解析

04-15 周一 GitHub仓库CI服务器配置过程文档 时间版本修改人描述2024年4月15日10:35:52V0.1宋全恒新建文档2024年4月17日10:33:20v1.0宋全恒完成github actions CI的配置和工作流配置文件解读文档的撰写 简介 一些基础概念 前提知识 仓库介绍 地址镜像介绍https://github.…

GIT上超火的阿里内部1000页Java核心笔记,啃完竟然拿到阿里P7offer!

除了ReetrantLock&#xff0c;你还接触过JUC中的哪些并发工具&#xff1f; 请谈谈ReadWriteLock 和StampedLock。 如何让Java的线程彼此同步&#xff1f;你了解过哪些同步器&#xff1f;请分别介绍下。 CyclicBarrier和CountDownLatch看起来很相似&#xff0c;请对比下呢&am…

Django中的数据库优化与ORM性能调优【第169篇—ORM性能调优】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 Django中的数据库优化与ORM性能调优 在开发基于Django的Web应用程序时&#xff0c;数据库是…

让一个元素在网页上跟随网页窗口大小变化始终保持上下左右居中

废话少说&#xff0c;直接上代码&#xff0c;懂的都懂&#xff1a; <!DOCTYPE html> <html style"font-size: 100px;"> <head><meta http-equiv"Content-Type" content"text/html;charsetUTF-8"><style type"te…

CTFHUB-技能树-Web前置技能-文件上传(前端验证—文件头检查)

CTFHUB-技能树-Web前置技能-文件上传&#xff08;前端验证—文件头检查&#xff09; 文章目录 CTFHUB-技能树-Web前置技能-文件上传&#xff08;前端验证—文件头检查&#xff09;前端验证—文件头检查题目解析 各种文件头标志 前端验证—文件头检查 题目考的是&#xff1a;pn…

Spring之CGLIB和JDK动态代理底层实现

目录 CGLIB 使用示例-支持创建代理对象&#xff0c;执行代理逻辑 使用示例-多个方法&#xff0c;走不同的代理逻辑 JDK动态代理 使用示例-支持创建代理对象&#xff0c;执行代理逻辑 Spring会自动在JDK动态代理和CGLIB之间转换: 1、如果目标对象实现了接口&#xff0c;默…

【计组】计算机系统概述

文章目录 前言正文计算机的发展历程什么是计算机系统硬件的发展历程软件的发展 计算机硬件的基本组成冯诺依曼体系结构(存储程序型电脑)现代计算机的结构 各硬件的工作原理主存储器的基本组成运算器的基本组成控制器的基本组成计算机的工作过程 计算机系统的层次结构计算机的性…

AWS Key disabler:AWS IAM用户访问密钥安全保护工具

关于AWS Key disabler AWS Key disabler是一款功能强大的AWS IAM用户访问密钥安全保护工具&#xff0c;该工具可以通过设置一个时间定量来禁用AWS IAM用户访问密钥&#xff0c;以此来降低旧访问密钥所带来的安全风险。 工具运行流程 AWS Key disabler本质上是一个Lambda函数&…

Go 语言中的 GIF 图像处理完全指南:`image/gif`的技术与实践

Go 语言中的 GIF 图像处理完全指南&#xff1a;image/gif的技术与实践 概述安装与基础设置导入 image/gif 包初步配置示例&#xff1a;设置一个简单的 GIF 编码环境 读取与解码 GIF 图像读取 GIF 文件解析 GIF 数据 创建与编码 GIF 图像创建 GIF 图像编码 GIF 图像 处理 GIF 动…

书生·浦语大模型实战训练营第二期第四节--Xtuner微调LLM--notebook

XTuner微调LLM课程笔记 一、Finetune简介 1.为什么模型要做微调&#xff1f; 现在其实大部分的大模型应该叫做“基座模型”&#xff0c;也就是基于普遍性的任务去进行与训练的&#xff0c;所以如果想让它落地在特定的下游领域中&#xff0c;它的表现必然是不如在领域内训练的模…

【devops】 阿里云挂载云盘 | 扩展系统硬盘 | 不重启服务器增加硬盘容量

扩容分区和文件系统&#xff08;Linux&#xff09; 文档地址 https://help.aliyun.com/zh/ecs/user-guide/extend-the-partitions-and-file-systems-of-disks-on-a-linux-instance?spm5176.smartservice_service_robot_chat_new.help.dexternal.4ac4f625Ol66kL#50541782adxmp…

Go 之 sync.Mutex 加锁失效现象

我先声明一下&#xff0c;并不是真的加锁失效&#xff0c;而是我之前的理解有误&#xff0c;导致看起来像是加锁失效一样。于是乎记录一下&#xff0c;加深一下印象。 我之前有个理解误区&#xff08;不知道大家有没有&#xff0c;有的话赶紧纠正一下——其实也是因为我这块的…

【在线OJ系统】自定义注解实现分布式ID无感自增

实现思路 首先自定义参数注解&#xff0c;然后根据AOP思想&#xff0c;找到该注解作用的切点&#xff0c;也就是mapper层对于mapper层的接口在执行前都会执行该aop操作&#xff1a;获取到对于的方法对象&#xff0c;根据方法对象获取参数列表&#xff0c;根据参数列表判断某个…

html接入高德地图

1.申请key key申请地址&#xff1a;https://console.amap.com/dev/key/app 官方文档 https://lbs.amap.com/api/javascript-api-v2/summary 2.html接入示例 需要将YOUR_KEY替换成自己的key <!doctype html> <html> <head><meta charset"utf-…