jsPDF 快速上手与深入实践:在浏览器与 Node.js 中纯客户端生成 PDF
jsPDF 快速上手与深入实践在浏览器与 Node.js 中纯客户端生成 PDF【免费下载链接】jsPDFClient-side JavaScript PDF generation for everyone.项目地址: https://gitcode.com/gh_mirrors/js/jsPDFjsPDF 是一个纯 JavaScript 的 PDF 生成库目标是面向所有人的客户端 PDF 生成Client-side JavaScript PDF generation for everyone。本指南以仓库根目录 README.md 为主线完整覆盖安装方式、浏览器/Node.js/AMD/全局变量等模块格式的使用方法、Unicode/自定义字体集成、Node 文件读取安全策略、可选依赖管理以及 compat/advanced 双 API 模式并结合 src/jspdf.js、src/index.js、src/modules/ 等源码给出实现级佐证。读完本文你将能够在浏览器端用几行代码生成并下载 PDF在 Node 端安全地读写文件并正确接入中文字体与构建工具Webpack/Vue CLI/Angular/React。一、安装npm、yarn 与 CDN 三种方式README 推荐的安装方式是使用 npm或 yarn安装后即以依赖形式进入你的工程npm install jspdf --save # 或 yarn add jspdf如果你希望始终获取最新版本也可以通过 unpkg CDN 以script标签方式直接引入 UMD 构建产物script srchttps://unpkg.com/jspdflatest/dist/jspdf.umd.min.js/scriptdist 目录中的文件类型README 明确指出包的dist目录包含不同种类的文件仓库中的 package.json 也印证了这些入口main、module、browser、exports字段均指向dist下的不同构建jspdf.es.*.js现代 ES2015 模块格式供打包工具进行 tree-shakingjspdf.node.*.js面向 Node 运行使用文件操作而非浏览器 API 来加载/保存文件jspdf.umd.*.jsUMD 模块格式可用于 AMD 或script标签直接加载polyfills*.js面向 IE 等旧浏览器的必需 polyfill。ES 变体通过core-js引入所有必需 polyfillUMD 变体则是自包含的。从 rollup.config.js 可以确认这些产物由同一套源码src/index.js为输入经 Rollup 分别以es、cjsNode与umd三种格式构建其中es/cjs产物把 package.json 中的 dependencies 与 optionalDependencies 声明为 external不打包进产物而 UMD 产物只将可选依赖 external。通常你不需要在 import 语句中指定具体文件构建工具或 Node 会自动解析出正确文件直接import jspdf即可。二、最小用法三行代码生成并下载 PDFimport { jsPDF } from jspdf; // 默认导出为 a4 纸张、纵向portrait、单位毫米mm const doc new jsPDF(); doc.text(Hello world!, 10, 10); doc.save(a4.pdf);new jsPDF()的默认行为a4/纵向/mm在源码中有明确体现src/jspdf.js 中format format || a4、orientation缺省取pportrait、unit unit || mm共同构成了这套默认值。自定义纸张尺寸、方向与单位README 给出的官方示例演示了横版 2×4 英寸的 PDF 生成// Landscape export, 2×4 inches const doc new jsPDF({ orientation: landscape, unit: in, format: [4, 2] }); doc.text(Hello world!, 1, 1); doc.save(two-by-four.pdf);结合 src/jspdf.js 的构造器注释可以梳理出完整的可用取值orientationportrait或landscape也支持简写p/l默认 portraitunitpt点、mm、cm、in英寸、px、pc、em、ex。注意若想获得px单位下的正确缩放需要启用 hotfix即传入hotfixes: [px_scaling]format既支持预设名称a0–a10、b0–b10、c0–c10、dl、letter、government-letter、legal、junior-legal、ledger、tabloid、credit-card也支持以数值数组自定义尺寸如[595.28, 841.89]即 A4 的 pt 尺寸。自定义数组传入后由getPageFormat之外的路径直接使用见 src/jspdf.js 的_addPage处理。除上述三个常用选项外构造器还支持putOnlyUsedFonts仅把用到的字体写入 PDF、compress压缩生成的 PDF、precision元素位置精度默认 16、userUnit、hotfixes以及encryption见 src/jspdf.js。三、在 Node.js 中运行jsPDF 也可以在 Node 中直接生成并保存 PDF 文件const { jsPDF } require(jspdf); // 会自动加载 node 版本 const doc new jsPDF(); doc.text(Hello world!, 10, 10); doc.save(a4.pdf); // 将文件保存到当前工作目录之所以require(jspdf)能自动加载 Node 版本是因为 package.json 的exports字段按条件导出node环境解析到./dist/jspdf.node.min.jsbrowser环境解析到./dist/jspdf.es.min.js。Node 版本使用文件操作fs而非浏览器 API 来加载和保存文件这一实现位于 src/modules/fileloading.js。四、其他模块格式AMD 与全局变量除了 ES Module 与 CommonJSjsPDF 还支持 AMD 和全局变量两种加载方式README 给出了完整示例AMDrequire([jspdf], ({ jsPDF }) { const doc new jsPDF(); doc.text(Hello world!, 10, 10); doc.save(a4.pdf); });Globalsscript标签引入 UMD 构建后const { jsPDF } window.jspdf; const doc new jsPDF(); doc.text(Hello world!, 10, 10); doc.save(a4.pdf);仓库的 examples/basic.html 展示了 UMD 引入的实际用法先script src../dist/jspdf.umd.js加载再通过window.jspdf.jsPDF取用构造函数。这一兼容矩阵ESM/Node/AMD/Globals也正是dist中多套构建产物存在的原因并且仓库在test/deployment/下分别维护了 amd、esm、globals、typescript、webworker 等多套部署测试来保证各加载方式可用。五、安全输入清洗与 Node 文件读取权限输入清洗README 强烈建议在把用户输入传给 jsPDF 之前务必先做清洗sanitize。jsPDF 本身不承担 HTML 消毒职责凡是来自用户的字符串内容都应先经过消毒处理再写入 PDF避免注入风险。Node 下读取本地文件系统的限制当在 Node 中运行时jsPDF默认禁止读取本地文件系统。README 给出了两种放行方式安全性有强有弱方式一强烈推荐使用 Node 的权限标志由运行时强制实施访问控制node --permission --allow-fs-read... ./scripts/generate.js注意--allow-fs-read必须包含所有被 import 的 JavaScript 文件包括全部依赖否则运行时也会因权限不足而拒绝读取。方式二不推荐作为首选在脚本中设置jsPDF.allowFsReadimport { jsPDF } from jspdf; const doc new jsPDF(); doc.allowFsRead [./fonts/*, ./images/logo.png]; // 允许 ./fonts 下所有文件以及单个文件README 明确警告推荐使用 Node 标志而非allowFsRead因为标志由运行时强制执行安全性更强。从实现上看src/modules/fileloading.js 的nodeReadFilejsPDF 的读取流程是先检查是否存在process.permissionNode 权限 API或this.allowFsRead两者皆无则直接抛错随后把路径realpathSync解析为真实路径若process.permission拒绝则抛权限错误最后按allowFsRead中的模式匹配——既支持精确路径也支持以单个*结尾的前缀通配例如./assets/*匹配该目录下所有路径以./assets/开头的文件。若process.permission可用它会先被检查即使allowFsRead放行也无法绕过运行时的拒绝。可选依赖与 Webpack externalsjsPDF 的部分功能依赖可选依赖optionalDependencies见 package.json例如html方法依赖html2canvas且当传入字符串形式的 HTML 文档时还依赖dompurify。jsPDF 会在需要时动态加载它们——src/modules/html.js 的loadHtml2Canvas/loadDomPurify实现说明在 ES 构建下通过动态import()加载在 CJS/AMD 下则用require/require([...])加载并兼容全局变量globalObject[html2canvas]/globalObject[DOMPurify]已存在的情况。构建工具如 Webpack会自动为每个可选依赖生成独立 chunk。如果应用不使用这些可选依赖可以通过 externals 阻止 Webpack 生成对应 chunkREADME 给出的 webpack.config.js 示例// webpack.config.js module.exports { // ... externals: { // 只把你【没有使用】的依赖声明为 externals canvg: canvg, html2canvas: html2canvas, dompurify: dompurify } };对应不同框架的处理方式README 原述Vue CLI通过vue.config.js新项目需先创建中的 configureWebpack 或 chainWebpack 属性定义 externalsAngular使用 custom webpack builders 定义 externalsReactcreate-react-app通过react-app-rewired或 eject 方式定义 externals。TypeScript 与其他框架jsPDF 可以像任何第三方库一样被导入兼容所有主流工具链与框架并且提供 TypeScript 类型声明文件仓库中的 types/index.d.tspackage.json的types/typings字段均指向它import { jsPDF } from jspdf;Meteor 项目可以这样添加meteor add jspdf:corePolyfillsjsPDF 依赖现代浏览器 API。要在 IE 等旧浏览器中使用需要加载 polyfillimport jspdf/dist/polyfills.es.js;或者加载预打包的 polyfill 文件不推荐可能重复加载 polyfill但小型应用或快速 POC 仍可用。polyfill 产物同样由 Rollup 从 src/polyfills.js 构建见 rollup.config.js 的umdPolyfills/esPolyfills配置UMD 变体自包含所有 polyfillES 变体则通过core-js引入。六、Unicode / UTF-8 与自定义字体PDF 的 14 种标准字体仅覆盖 ASCII 码页。要输出 UTF-8 文本例如中文必须集成包含所需字形glyph的自定义字体。jsPDF 支持.ttf字体文件——如果字体不含中文等所需字形PDF 中会显示乱码所以务必确认所选字体包含目标字符集。方式一使用 fontconverter 转换工具仓库自带字体转换工具 fontconverter/fontconverter.html源码位于 fontconverter/ 目录含 FileSaver.js、filereader.js 等辅助脚本。它会将提供的 ttf 文件内容转为 base64 字符串并生成一段 js 代码文件把生成的 js 文件加入项目后即可用setFont方法书写 UTF-8 文本。方式二运行时动态加载 ttf也可以直接用fetch或XMLHttpRequest把 ttf 文件作为二进制字符串加载再注册到 PDFconst doc new jsPDF(); const myFont ... // 以二进制字符串形式加载 *.ttf 字体文件 // 把字体加入 jsPDF 的 vFS虚拟文件系统 doc.addFileToVFS(MyFont.ttf, myFont); doc.addFont(MyFont.ttf, MyFont, normal); doc.setFont(MyFont);这三个 API 的实现分别位于addFileToVFS见 src/modules/vfs.js将文件内容存入this.internal.vFS[filename]addFont见 src/jspdf.js注册字体的 PostScript 名、字体名、样式如normal与字重setFont见 src/jspdf.js切换当前活动字体内部通过getFont(fontName, fontStyle, ...)解析。字体的实际解析发生在addFont事件处理中src/modules/ttfsupport.js如果是标准字体则直接从 vFS 取 base64 内容否则要求字体已存在于 vFS否则抛出Font does not exist in vFS, import fonts or remove declaration doc.addFont(...)这样的错误提示。TTF 文件内容会被转换为Uint8Array供后续字形度量使用。七、高级功能compat 与 advanced 双 API 模式jsPDF 与 yWorks fork 合并后引入了大量新特性但部分特性是破坏性 API 变更因此提供了两种 API 模式compat 模式与 MrRio 原版 API 完全一致兼容所有插件但部分高级特性如变换矩阵、图案 pattern不可用。这是默认模式advanced 模式即 yWorks fork 的 API支持 pattern、FormObject、变换矩阵等全部高级特性。在两种模式间切换doc.advancedAPI(doc { // 你的代码 }); // 或 doc.compatAPI(doc { // 你的代码 });回调执行完毕后jsPDF 会自动切回原来的 API 模式。从 src/jspdf.js 的实现可以看到advancedAPI()内部会保存图形状态、压入一个坐标变换矩阵把用户坐标系转换到 PDF 坐标系并把默认路径操作改为n不描边compatAPI()则恢复图形状态并把默认路径操作改回S描边API.advancedAPI(body)/API.compatAPI(body)支持可选回调传入回调时执行完自动切回原模式不传回调时则只切换模式、需要手动调用对应方法切回还有API.isAdvancedAPI()用于查询当前是否处于 advanced 模式某些方法如需要变换矩阵的功能会通过advancedApiModeTrap检查若不在 advanced 模式下调用会抛出... is only available in advanced API mode. You need to call advancedAPI() first.错误。注意使用约束回调内或两次调用之间的saveGraphicsState/restoreGraphicsState调用必须配对在切回 compat 模式前beginFormObject或beginTilingPattern必须由对应方法关闭。八、演示、示例与测试仓库提供了丰富的上手资源examples/basic.html 及其同目录下的 examples/js/basic.js 等示例脚本覆盖文本、图形、字体等基础元素浏览器直接打开即可交互运行examples/vite/ 是一个完整的 Vite 工程示例含 examples/vite/package.json 与 examples/vite/main.js展示了在现代打包工具下的接入方式文档站点源码位于 docs/由 JSDoc 从源码生成配置见 jsdoc.json包含各模块addImage、annotations、html、utf8、vfs 等的 API 文档页面。构建与测试命令见 package.json 的scriptsnpm run build使用 Rollup 构建 distnpm test依次运行 Node 测试Jasmine与浏览器测试KarmaChromeHeadlessnpm run test-local可依次运行 unit、node、amd、esm、globals、typescript、webworker 全套部署测试仓库在 test/ 目录下维护了大量 specs 与参考 PDFtest/reference/*.pdf用于回归对比。九、贡献与许可jsPDF 欢迎社区贡献如果觉得缺少特性或发现 bug可以查看 CONTRIBUTING.md 了解构建与测试指引并参考 CODE_OF_CONDUCT.md。Bug 报告应遵循 README 的建议提供最小可复现示例mcve、格式化良好的代码、可运行的示例并尽量证明问题确实与 jsPDF 相关而非所用框架导致。安全问题请遵循 SECURITY.md 的披露流程。项目采用 MIT 许可LICENSE版权归 James Hall 与 yWorks GmbH 所有2010-2025 / 2015-2025允许自由使用、修改与分发。【免费下载链接】jsPDFClient-side JavaScript PDF generation for everyone.项目地址: https://gitcode.com/gh_mirrors/js/jsPDF创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Element Plus 2026实战指南:Vue 3后台管理系统的组件库选型与工程化落地

Element Plus 2026实战指南:Vue 3后台管理系统的组件库选型与工程化落地

Element Plus 这个组件库,我从它还是 Element UI 的 Alpha 版本时期就开始跟了,一路用到 2026 年的今天,可以说见证了 Vue 生态里这套组件库从小众走向事实标准的过程。如果你是刚接触 Vue 3 生态,或者正打算把手头的老项目迁移到…

2026/9/21 1:22:30 阅读更多 →
Vue CLI 快速上手指南:安装、创建项目与 vue create / vue ui 全解析

Vue CLI 快速上手指南:安装、创建项目与 vue create / vue ui 全解析

Vue CLI 快速上手指南:安装、创建项目与 vue create / vue ui 全解析 【免费下载链接】vue-cli 🛠️ webpack-based tooling for Vue.js Development 项目地址: https://gitcode.com/gh_mirrors/vu/vue-cli Vue CLI 是 Vue.js 官方提供的基于 web…

2026/9/21 1:23:50 阅读更多 →
ESXi 8.0物理服务器部署实战:USB启动、UEFI适配与硬件兼容性校验

ESXi 8.0物理服务器部署实战:USB启动、UEFI适配与硬件兼容性校验

1. 这不是“装个系统”那么简单:ESXi 8.0 安装的本质是重构服务器的底层运行逻辑你搜“VMware ESXi 8.0 安装教程”,点开十篇,八篇开头就甩出一张U盘启动界面截图,然后告诉你“按F11选U盘启动”,再下一步就是“回车继续…

2026/9/21 0:56:01 阅读更多 →

最新新闻

RTL8189 SDIO WiFi在Luban-Lite上的移植与调试实战

RTL8189 SDIO WiFi在Luban-Lite上的移植与调试实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 1:30:50 阅读更多 →
VS Code 插件总结:这次用 TaoToken 让 Codex 核一遍清单

VS Code 插件总结:这次用 TaoToken 让 Codex 核一遍清单

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 1:30:50 阅读更多 →
python-sdk 服务端 Prompts 全指南:从声明、渲染到运行时动态管理

python-sdk 服务端 Prompts 全指南:从声明、渲染到运行时动态管理

python-sdk 服务端 Prompts 全指南:从声明、渲染到运行时动态管理 【免费下载链接】python-sdk The official Python SDK for Model Context Protocol servers and clients 项目地址: https://gitcode.com/gh_mirrors/pythonsd/python-sdk 导读 Prompts&…

2026/9/21 1:30:50 阅读更多 →
CKKS参数调优实战指南:SEAL库静默崩溃的根源与解法

CKKS参数调优实战指南:SEAL库静默崩溃的根源与解法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 1:30:50 阅读更多 →
Trea 模型请求失败?检查 TaoToken 的 Base URL 格式

Trea 模型请求失败?检查 TaoToken 的 Base URL 格式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 1:30:50 阅读更多 →
Codex CLI 启动链路拆解:从二进制到 Agent 就绪的完整过程

Codex CLI 启动链路拆解:从二进制到 Agent 就绪的完整过程

我第一次完整盯完 Codex CLI 从敲下回车到真正开始干活的全过程,是在一个规模不小的 monorepo 里。当时仓库里有几百个包,codex 启动后没有立刻跳出对话输入框,而是先花了几秒扫描目录、加载配置、确认认证信息,然后才把终端交还给…

2026/9/21 1:29:49 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →