使用 CDN 在国内加载本地 PDF 文件并处理批注:PDF.js 5.x 实战指南

PDF.js 是一个强大的开源 JavaScript 库,用于在 Web 浏览器中渲染 PDF 文件。它由 Mozilla 开发,能够将 PDF 文档绘制到 HTML5 Canvas 或 SVG 上,无需任何本机代码或浏览器插件。对于许多需要在网页中展示 PDF 内容的应用场景来说,PDF.js 是一个非常理想的选择。

本文将重点探讨以下几个方面:

  1. 如何通过 CDN 在网页中引入 PDF.js 库。
  2. 在中国大陆地区选择哪些 CDN 服务以获得更好的访问速度和稳定性。
  3. 如何使用 PDF.js 加载用户选择的本地 PDF 文件。
  4. PDF.js 如何处理 PDF 文件中的批注,以及在使用批注功能时需要注意的事项。

我们将以 PDF.js 5.x 版本为例进行讲解,但核心原理同样适用于其他版本。

1. 通过 CDN 引入 PDF.js

使用 CDN (内容分发网络) 引入 PDF.js 是最常见和便捷的方式,它可以减轻服务器压力,并利用 CDN 节点的地理优势加速文件的传输。引入 PDF.js 主要需要两个文件:

  • pdf.min.js: PDF.js 的核心库,包含了主要的 API 和渲染逻辑。
  • pdf.worker.min.js: PDF.js 的 Worker 脚本,用于在后台线程中处理 PDF 的解析和渲染任务,避免阻塞主线程。

你需要在 HTML 文件的 <head><body> 标签中引入它们:

<script src="[CDN_URL_FOR_PDF.MIN.JS]"></script>
<script>// 必须设置 workerSrc 指向 worker 脚本的 URLpdfjsLib.GlobalWorkerOptions.workerSrc = '[CDN_URL_FOR_PDF.WORKER.MIN.JS]';
</script>

请将 [CDN_URL_FOR_PDF.MIN.JS][CDN_URL_FOR_PDF.WORKER.MIN.JS] 替换为实际的 CDN 链接。注意,workerSrc 必须设置,并且核心库和 worker 脚本的版本号必须严格匹配。

2. 中国大陆地区 CDN 选择建议

对于在中国大陆地区访问的用户,受限于网络环境,直接使用一些国际 CDN(如 Cloudflare CDN)可能会遇到访问速度慢或不稳定的问题。为了获得更好的用户体验,建议选择在中国有部署节点或与中国本地服务商有合作的 CDN。

以下是两个在中国大陆地区表现通常较好的开源库 CDN:

a. jsDelivr

jsDelivr 是一个免费的、高速的开源 CDN,它与中国的网宿、七牛云等服务商有深度合作,拥有广泛的中国大陆节点。对于开源库来说,jsDelivr 是一个非常可靠的选择。

你可以在 jsDelivr 上通过 npm/package-name@version/file-path 的格式找到 PDF.js 的文件。PDF.js 的 npm 包名是 pdfjs-dist

例如,如果你需要引入接近 5.x 的某个稳定版本,你需要查找具体的版本号(请注意,pdf.js 版本号通常是构建号,例如 4.0.269 是一个近期版本,请替换为你实际需要的 5.x 对应的版本号):

  • 核心库 (pdf.min.js):
    https://cdn.jsdelivr.net/npm/pdfjs-dist@版本号/build/pdf.min.js
    例:https://cdn.jsdelivr.net/npm/pdfjs-dist@4.0.269/build/pdf.min.js
  • Worker 脚本 (pdf.worker.min.js):
    https://cdn.jsdelivr.net/npm/pdfjs-dist@版本号/build/pdf.worker.min.js
    例:https://cdn.jsdelivr.net/npm/pdfjs-dist@4.0.269/build/pdf.worker.min.js

请访问 jsDelivr 官网或利用其搜索功能,查找 pdfjs-dist 包下您需要的具体 5.x 版本号和文件路径。

b. BootCDN

BootCDN 是一个由国内团队维护的、专注于服务国内开发者的开源库 CDN 平台。它同步了许多国外常用开源库的资源,并使用国内的 CDN 服务商提供加速。

你可以在 BootCDN 上搜索 “pdf.js” 或 “pdfjs-dist” 来找到对应的资源。BootCDN 的 URL 格式通常是 cdn.bootcdn.net/ajax/libs/library-name/version/file-path

例如,如果你需要引入接近 5.x 的某个版本(同样,请替换为你实际需要的 5.x 对应的版本号):

  • 核心库 (pdf.min.js):
    https://cdn.bootcdn.net/ajax/libs/pdf.js/版本号/pdf.min.js
    例:https://cdn.bootcdn.net/ajax/libs/pdf.js/4.0.269/pdf.min.js
  • Worker 脚本 (pdf.worker.min.js):
    https://cdn.bootcdn.net/ajax/libs/pdf.js/版本号/pdf.worker.min.js
    例:https://cdn.bootcdn.net/ajax/libs/pdf.js/4.0.269/pdf.worker.min.js

请访问 BootCDN 官网查找您需要的 pdf.js 版本对应的具体文件路径。

重要: 在选择 CDN 后,请务必替换 HTML 中的 [CDN_URL_FOR_PDF.MIN.JS][CDN_URL_FOR_PDF.WORKER.MIN.JS] 为您选择的 CDN 提供的实际链接,并确保两个文件的版本号一致。

3. 加载本地 PDF 文件

PDF.js 可以通过多种方式加载 PDF 源,包括 URL、 TypedArray (如 ArrayBuffer)、以及 Blob。要加载本地文件,最常用的方式是结合 <input type="file">FileReader API,将文件读取为 ArrayBuffer,然后传递给 PDF.js。

首先,在 HTML 中添加一个用于用户选择本地文件的输入框,以及一个用于渲染 PDF 的 canvas 元素:

<input type="file" id="pdfFile" accept=".pdf">
<canvas id="the-canvas"></canvas>

然后,使用 JavaScript 监听文件输入框的 change 事件,读取文件内容并使用 PDF.js 加载和渲染:

document.getElementById('pdfFile').addEventListener('change', function(event) {var file = event.target.files[0]; // 获取用户选择的第一个文件// 检查文件类型if (file.type !== "application/pdf") {alert(file.name + " 不是一个有效的 PDF 文件。");return;}var fileReader = new FileReader();// 当文件读取完成后fileReader.onload = function() {// 文件内容作为 ArrayBuffervar typedarray = new Uint8Array(this.result);// 使用 PDF.js 加载 PDF 文档const loadingTask = pdfjsLib.getDocument(typedarray);loadingTask.promise.then(function(pdf) {console.log('PDF 加载成功');// 以第一页为例进行渲染pdf.getPage(1).then(function(page) {console.log('页面加载成功');var scale = 1.5; // 缩放比例var viewport = page.getViewport({ scale: scale });// 获取 canvas 元素及其上下文var canvas = document.getElementById('the-canvas');var context = canvas.getContext('2d');// 设置 canvas 的尺寸与页面 viewport 匹配canvas.height = viewport.height;canvas.width = viewport.width;// 渲染页面到 canvasvar renderContext = {canvasContext: context,viewport: viewport};var renderTask = page.render(renderContext);renderTask.promise.then(function() {console.log('页面渲染完成');});});}, function(reason) {// PDF 加载失败的处理console.error('PDF 加载失败: ' + reason);});};// 读取文件内容为 ArrayBufferfileReader.readAsArrayBuffer(file);
});

这段代码演示了如何加载用户选择的本地 PDF 文件,并将其第一页渲染到页面上指定的 canvas 元素中。你可以根据需要扩展代码,实现多页加载、滚动、缩放等功能。

4. 关于批注功能

当涉及到 PDF 批注时,需要明确一点:PDF.js 的核心功能是渲染和显示 PDF 文档内容,这包括显示 PDF 文件本身已经包含的标准批注类型(如文本标记、高亮、形状等)。

但是,PDF.js (包括 5.x 版本) 本身并不提供创建**、编辑保存新批注的内置交互式工具或 API。**

这意味着:

  • 如果你加载的本地 PDF 文件本身已经包含了批注,PDF.js 在渲染时会尝试将其显示出来。通常情况下,如果批注是标准的 PDF 批注类型,它们会随着页面内容一起被绘制到 Canvas 上,或者作为独立的图层数据提供(需要进一步处理)。
  • 如果你希望实现用户在网页上添加修改删除批注的功能,仅仅依靠 PDF.js 的核心库是不够的。你需要自己实现一套完整的批注交互逻辑和数据管理系统。这通常非常复杂,需要:
    • 监听鼠标事件,识别用户在 Canvas 上的操作。
    • 在 Canvas 上方叠加一个交互层(例如另一个 Canvas 或 SVG)来绘制批注的图形表示。
    • 根据用户操作,创建或修改批注的数据结构。
    • 将这些批注数据保存下来,如果需要保存回 PDF 文件本身,则需要更高级的库(如 PDF-LIB,它可以在浏览器端修改 PDF 文件,但功能有限)或依赖后端服务来处理 PDF 文件的修改。

建议:

如果你的需求是实现功能完善的交互式批注工具,考虑到其复杂性,你可能需要:

  • 深入研究 PDF.js 的底层 API 如何获取批注信息,并结合 Canvas 或 SVG 绘图技术自行实现批注的绘制和交互逻辑。
  • 考虑使用第三方的 JavaScript PDF SDK 或库,这些库通常基于 PDF.js 或其他渲染引擎构建,并提供了开箱即用的批注创建、编辑和保存功能。一些库声称与 PDF.js 兼容,或者提供了更高级的 API 来处理 PDF 文档的结构和批注。

总结

本文详细介绍了如何在中国大陆地区选择合适的 CDN(如 jsDelivr 或 BootCDN),通过 CDN 引入 PDF.js 5.x 版本,并使用 JavaScript 加载用户选择的本地 PDF 文件并将其渲染到网页的 Canvas 元素上。

同时,我们澄清了 PDF.js 在批注功能方面的能力:它能很好地显示 PDF 中已有的批注,但不包含创建和编辑批注的内置工具。如果你需要完整的交互式批注功能,需要进行额外的开发或考虑使用更专业的第三方库。

希望这篇博文对你在使用 PDF.js 构建 Web PDF 应用时有所帮助!

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

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

相关文章

网络化:DevOps 工程的必要基础(Networking: The Essential Foundation for DevOps Engineering)

李升伟 编译 理解网络化基础知识 你是否曾想过是什么真正让卓越的DevOps工程师与众人区别开来&#xff1f;答案是网络化。是的&#xff0c;对网络的基本理解不仅仅是有帮助的——它是绝对必要的。在当今以微服务、容器和分布式系统为主宰的互联互通世界中&#xff0c;对网络原…

C++基本知识 —— 缺省参数·函数重载·引用

C基本知识 —— 缺省参数函数重载引用 1. 缺省参数2. 函数重载3. 引用3.1 引用的基础知识3.2 引用的作用3.3 const 引用3.4 指针与引用的关系 1. 缺省参数 什么是缺省参数&#xff1f;缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数的时候&#xff0c;如…

Rust 官方文档:人话版翻译指南

鉴于大部分翻译文档都不太会说人话&#xff0c;本专栏主要内容为 rust 程序设计语言、rust 参考手册、std 库 等官方文档的中译中。

FlySecAgent:——MCP全自动AI Agent的实战利器

最近&#xff0c;出于对人工智能在网络安全领域应用潜力的浓厚兴趣&#xff0c;我利用闲暇时间进行了深入研究&#xff0c;并成功开发了一款小型轻量化的AI Agent安全客户端FlySecAgent。 什么是 FlySecAgent&#xff1f; 这是一个基于大语言模型和MCP&#xff08;Model-Contr…

实战项目5(08)

目录 任务场景一 【r1配置】 【r2配置】 【r3配置】 ​​​​​​​任务场景二 【r1配置】 【r2配置】 ​​​​​​​任务场景一 按照下图完成网络拓扑搭建和配置 任务要求&#xff1a; 通过在路由器R1、R2和R3上配置静态路由&#xff0c;实现网络中各终端PC能够正常…

基于Kubernetes的Apache Pulsar云原生架构解析与集群部署指南(下)

文章目录 k8s安装部署Pulsar集群前期准备版本要求 安装 Pulsar Helm chart管理pulsarClustersBrokersTopic k8s安装部署Pulsar集群 前期准备 版本要求 Kubernetes 集群&#xff0c;版本 1.14 或更高版本Helm v3&#xff08;3.0.2 或更高版本&#xff09;数据持久化&#xff…

C35-数组和函数开发初见

一 数组作为函数的参数 用于传递数组中的某一个元素→意义不大 数组名当做函数实际参数 示例 代码 #include <stdio.h>//封装函数PrintArr void PrintArr(int arr[3]){int i;for(i0;i<3;i){printf("%d ",arr[i]);}putchar(\n);}//主函数 int main() { …

【小沐学GIS】基于C++绘制二维瓦片地图2D Map(QT、OpenGL、GIS)

&#x1f37a;三维数字地球系列相关文章如下&#x1f37a;&#xff1a;1【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;OpenGL、glfw、glut&#xff09;第一期2【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;OpenGL、glfw、glut、GIS&#xff09;第二期3【小沐学…

idea左侧项目资源管理器不见了处理

使用idea误触导致&#xff0c;侧边栏和功能栏没了&#xff0c;如何打开&#xff1f; 1.打开文件&#xff08;File&#xff09; 2. 打开设置&#xff08;Settings&#xff09; 3.选择Appearance&Behavior--->Appearance划到最下面&#xff0c;开启显示工具栏和左侧并排布…

[Java实战]Spring Boot 静态资源配置(十三)

[Java实战]Spring Boot 静态资源配置&#xff08;十三&#xff09; 引言 静态资源&#xff08;如 HTML、CSS、JavaScript、图片等&#xff09;是 Web 应用的基石。Spring Boot 通过自动化配置简化了静态资源管理&#xff0c;但面对复杂场景&#xff08;如多模块项目、CDN 集成…

多模态大语言模型arxiv论文略读(六十九)

Prompt-Aware Adapter: Towards Learning Adaptive Visual Tokens for Multimodal Large Language Models ➡️ 论文标题&#xff1a;Prompt-Aware Adapter: Towards Learning Adaptive Visual Tokens for Multimodal Large Language Models ➡️ 论文作者&#xff1a;Yue Zha…

Python 基础语法与数据类型(七) - 函数的定义与调用 (def, return)

文章目录 为什么要使用函数&#xff1f;函数的定义 (def)函数的调用函数参数 (Parameters vs Arguments)返回值 (return)变量作用域 (简要了解)总结练习题练习题答案 **创作不易&#xff0c;请大家点赞加收藏&#xff0c;关注我&#xff0c;持续更新教程&#xff01;** 到目前为…

华为配置篇-RSTP/MSTP实验

MSTP 一、简介二、常用命令总结三、实验 一、简介 RSTP&#xff08;快速生成树协议&#xff09;​ RSTP&#xff08;Rapid Spanning Tree Protocol&#xff09;是 STP 的改进版本&#xff0c;基于 ​​IEEE 802.1w 标准​​&#xff0c;核心目标是解决传统 STP 收敛速度慢的问…

Docker Compose 完全指南:从入门到生产实践

Docker Compose 完全指南&#xff1a;从入门到生产实践 1. Docker Compose 简介与核心价值 Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过一个 YAML 文件来配置应用的服务&#xff0c;只需简单命令就能创建和启动所有服务。 核心优势&#xff1a;…

Linux 离线安装 Docker 和 Docker Compose 最新版 的完整指南

一、准备工作 1. 下载安装包​&#xff08;需在有网络的机器操作&#xff09;&#xff1a; Docker 引擎&#xff1a;从官方仓库下载最新二进制包 wget https://download.docker.com/linux/static/stable/x86_64/docker-24.0.6.tgz​Docker Compose&#xff1a;下载最新二进制…

CSS: 选择器与三大特性

标签选择器 标签选择器就是选择一些HTML的不同标签&#xff0c;由于它们的标签需求不同&#xff0c;所以CSS需要设置标签去选择它们&#xff0c;为满足它们的需求给予对应的属性 基础选择器 标签选择器 <!DOCTYPE html> <head><title>HOME</title>…

鸿蒙跨平台开发教程之Uniapp布局基础

前两天的文章内容对uniapp开发鸿蒙应用做了一些详细的介绍&#xff0c;包括配置开发环境和项目结构目录解读&#xff0c;今天我们正式开始写代码。 入门新的开发语言往往从Hello World开始&#xff0c;Uniapp的初始化项目中已经写好了一个简单的demo&#xff0c;这里就不再赘述…

JavaSE核心知识点02面向对象编程02-08(异常处理)

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 JavaSE核心知识点02面向对象编程02-08&#…

【JVM-GC调优】

一、预备知识 掌握GC相关的VM参数&#xff0c;会基本的空间调整掌握相关工具明白一点&#xff1a;调优跟应用、环境有关&#xff0c;没有放之四海而皆准的法则 二、调优领域 内存锁竞争cpu占用io 三、确定目标 【低延迟】&#xff1a;CMS、G1&#xff08;低延迟、高吞吐&a…

基于单片机的电子法频率计

一、电子计数法测频率原理 通过门控控制闸门开关&#xff0c;闸门时间T自己设定&#xff0c;计数器计数脉冲个数N&#xff08;也就是待测信号&#xff09;&#xff0c;N个脉冲的时间间隔为δt,倒数即为信号的频率f,由此 δtT/N fN/T——信号频率 根据公式&#xff0c;如果考虑…