简述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
  >>
endobj

2 0 obj
  << /Type /Pages
     /Kids [3 0 R]
     /Count 1
     /MediaBox [0 0 300 144]
  >>
endobj

3 0 obj
  <<  /Type /Page
      /Parent 2 0 R
      /Resources
       << /Font
           << /F1
               << /Type /Font
                  /Subtype /Type1
                  /BaseFont /Times-Roman
               >>
           >>
       >>
      /Contents 4 0 R
  >>
endobj

4 0 obj
  << /Length 55 >>
stream
  BT
    /F1 18 Tf
    0 0 Td
    (Im liheng) Tj
  ET
endstream
endobj

xref
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 FileResponse

def 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对象中,并将其作为响应返回。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/553105.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Docker应用推荐个人服务器实用有趣的项目推荐

Wallabag&#xff1a;是一个开源的、自托管的文章阅读和保存工具。它允许你保存网页文章并进行离线阅读&#xff0c;去除广告和不必要的内容&#xff0c;以提供更好的阅读体验。Wallabag支持多种导入和导出格式&#xff0c;并提供了一些实用的功能&#xff0c;如标签、阅读列表…

Flutter 像素编辑器#03 | 像素图层

theme: cyanosis 本系列&#xff0c;将通过 Flutter 实现一个全平台的像素编辑器应用。源码见开源项目 【pix_editor】 《Flutter 像素编辑器#01 | 像素网格》《Flutter 像素编辑器#02 | 配置编辑》《Flutter 像素编辑器#03 | 像素图层》 上一篇我们实现了编辑配置&#xff0c;…

【R语言】组合图:散点图+箱线图+平滑曲线图+柱状图

用算数运算符轻松组合不同的ggplot图&#xff0c;如图&#xff1a; 具体代码如下&#xff1a; install.packages("devtools")#安装devtools包 devtools::install_github("thomasp85/patchwork")#安装patchwork包 library(ggplot2) library(patchwork) #p1是…

Spark/SparkSQL读取Hadoop LZO文件概述

一、前置配置 IDEA Maven安装配置 Scala&#xff08;可选&#xff09; Java Hadoop.dll&#xff08;可能需要&#xff0c;具体看有无相关错误信息&#xff09; hadoop-lzo-0.xx.xx.jar&#xff08;如果你的版本过高&#xff0c;需要到官网下载高版本&#xff0c;mvnrepository仓…

2024年——区块链技术进入全新高度

BTC生态蓬勃发展&#xff0c;以太坊的L1和L2模块化重塑智能合约生态。RAAS&#xff08;区块链即服务&#xff09;、Depin、并行EVM等技术的崛起&#xff0c;为区块链应用提供了更高的性能和可扩展性。以太坊再质押成为焦点。技术创新与日俱进&#xff0c;一同探索这个充满活力的…

优思学院|ISO45001职业健康安全管理体系是什么?

ISO45001:2018是新公布的国际标准规范&#xff0c;全球备受期待的职业健康与安全国际标准&#xff08;OH&S&#xff09;于2018年公布&#xff0c;并将在全球范围内改变工作场所实践。ISO45001将取代OHSAS18001&#xff0c;成为全球工作场所健康与安全的参考。 ISO45001:201…

HarmonyOS开发实例:【分布式新闻客户端】

介绍 本篇Codelab基于栅格布局、设备管理和多端协同&#xff0c;实现一次开发&#xff0c;多端部署的分布式新闻客户端页面。主要包含以下功能&#xff1a; 展示新闻列表以及左右滑动切换新闻Tab。点击新闻展示新闻详情页。点击新闻详情页底部的分享按钮&#xff0c;发现周边…

可见光相机曝光方式

可见光摄影中的曝光方式主要包括两种&#xff1a;卷帘曝光和全局曝光。它们之间的区别在于曝光过程中传感器或胶片感光部分的工作方式不同&#xff0c;这直接影响到图像捕获的效果和特性。 卷帘曝光&#xff08;Rolling Shutter&#xff09;&#xff1a; 工作原理&#xff1a;在…

工业自动化,3D视觉技术3C薄片自动化上料

随着制造业的快速发展&#xff0c;3C行业对薄片类零件的上料需求日益增长。传统的上料方式往往依赖于人工操作&#xff0c;效率低下且存在误差。为了解决这一问题&#xff0c;3D视觉技术应运而生&#xff0c;为3C薄片自动化上料提供了强大的技术支持。本文将探讨3D视觉技术如何…

美格智能出席紫光展锐第三届泛金融支付生态论坛,引领智慧金融变革向新

4月16日&#xff0c;以“融智创新&#xff0c;共塑支付产业新生态”为主题的紫光展锐第三届泛金融支付生态论坛在福州举办&#xff0c;来自金融服务机构、分析师机构、终端厂商、模组厂商等行业各领域生态伙伴汇聚一堂&#xff0c;探讨金融支付产业的机遇与挑战。作为紫光展锐重…

(4.6–4.12)投融资周报|共29笔公开投融资事件,基础设施继续领跑,游戏、RWA、Depi、NFT相关融資活躍

本周千万美金以上融资有6笔&#xff1a; 高性能的第 1 层区块链Monad完成了一轮2.25 亿美元的融资&#xff0c;投资方为Paradigm、Coinbase Ventures等。 互联网基础设施解决方案Auradine完成了8000 万美元的B轮融资&#xff0c;投资方为Celesta Capital、Mayfield等。 比特币…

利用大语言模型,矢量数据库实现数据库的智能搜索

目的 数据库使用SQL 语言查询数据&#xff0c;数据库的记录中要有一个关键字段&#xff08;通常称为主键字段&#xff0c;它的值在数据库列表中是唯一的&#xff09;,数据记录是结构化的. 如果你需要根据数据记录的内容来查询数据记录&#xff0c;就需要通过Select 语句在数据库…

【数学】主成分分析(PCA)的应用案例解析(Python)

接着上文PCA的数学详细推导过程&#xff0c;本文介绍使用Python结合图像压缩案例解释PCA的具体实现流程&#xff0c;以了解数据处理的一些方法 Jupyter Notebook file 文章目录 借助 scikit-learn 实现 PCA输入数据PCA降维并重建 手动实现 PCA 过程输入数据数据居中处理协方差矩…

自动驾驶(八十四)---------中间件对比分析

很久没有写博客了&#xff0c;CSDN无故非法删了我第82篇&#xff0c;让我很恼火&#xff0c;一直提不起兴趣重新写一遍第82篇。但回初心&#xff0c;知识需要用自己的语言输出&#xff0c;所以今天对比分析自动驾驶中间件&#xff1a; 1. 中间件介绍 在自动驾驶架构中&#xf…

【Git】git命令大全(持续更新)

本文架构 0.描述git简介术语 1.常用命令2. 信息管理新建git库命令更改存在库设置获取当前库信息 3.工作空间相关将工作空间文件添加到缓存区&#xff08;增&#xff09;从工作空间中移除文件&#xff08;删&#xff09;撤销提交 4.远程仓库相关同步远程仓库分支 &#xff08;持…

【学习笔记】Python大数据处理与分析——数据预处理

一、数据清洗 1、唯一值与重复值 获取唯一值的方法是采用unique()函数&#xff0c;用于Series对象&#xff1a; s1 pd.Series([2, 3, 4, 1, 2, 5, 3, 6, 4, 9, 5, 3, 4, 2, 1, 2])print(s1.unique()) →[2 3 4 1 5 6 9] 但unique()函数不能用于DataFrame对象&#xff0c;而d…

html接入百度地图

1.申请key key申请地址&#xff1a;https://lbsyun.baidu.com/apiconsole/key#/home 注意&#xff1a;白名单设置*则所有可访问&#xff0c;正式发布保证安全需修改为域名 官方文档 https://lbsyun.baidu.com/index.php?titlejspopularGL 2.html接入示例 <!DOCTYPE …

基于51单片机智能鱼缸仿真LCD1602显示( proteus仿真+程序+设计报告+讲解视频)

基于51单片机智能鱼缸仿真LCD显示 1. 主要功能&#xff1a;2. 讲解视频&#xff1a;3. 仿真4. 程序代码5. 设计报告6. 设计资料内容清单&&下载链接资料下载链接&#xff1a; 基于51单片机智能鱼缸仿真LCD显示( proteus仿真程序设计报告讲解视频&#xff09; 仿真图prot…

基于springboot+vue+Mysql的汽车租赁系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

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.…