News
首页  -  资讯  - 
使用 JavaScript 在 React 中实现 Word 转 PDF
使用 JavaScript 在 React 中实现 Word 转 PDF 在 React 前端工程中,实现 Word 文档到 PDF 格式的转换,是构建文档管理系统、在线合同签署及报表导出特性时的高频需求。相较于传统的后端转换方案,在浏览器端直接完成转换具有明显优势:文档内容无需离开客户设备,从根本上避免了传输过程中的资料泄露风险,同时有效降低了服务器端的计算与带宽开销。 本文将介绍一种基于 We...

使用 JavaScript 在 React 中实现 Word 转 PDF 在 React 前端工程中,实现 Word 文档到 PDF 格式的转换,是构建文档管理系统、在线合同签署及报表导出特性时的高频需求。相较于传统的后端转换方案,在浏览器端直接完成转换具有明显优势:文档内容无需离开客户设备,从根本上避免了传输过程中的资料泄露风险,同时有效降低了服务器端的计算与带宽开销。 本文将介绍一种基于 WebAssembly 工艺的纯前端转换方案,围绕其在实际 React 项目中的环境搭建、核心机制以及多种配置场景进行展开,为有类似需求的工程师提供参考。 一、技术原理简述 该方案的核心是一个运行在浏览器沙箱中的 WebAssembly(WASM)模块。它将文档处理引擎编译为浏览器可直接执行的二进制代码,从而在客户端实现高性能的文档读写与转换。 由于 WASM 环境无法直接访问本地文件系统,该方案通过一个 虚拟文件系统(VFS) 来管理文件。整个转换流程可概括为三个步骤: 写入 :通过特定 API 将项目 public 目录下的字体文件和待转换文档加载到 VFS 中。 处理 : Document 对象从 VFS 读取源文件,执行转换操作,并将结果输出至 VFS。 读取 :转换完成后,从 VFS 中读取生成的 PDF 二进制数据,通过浏览器 API 触发下载。 理解这一基于内存的数据流转模型,有助于更好地进行后续的代码调试与改进。 二、项目初始化与环境配置 1. 安装依赖包 在项目根目录执行以下命令安装所需的助手包: npm i spire.office 2. 迁移运行时文件 安装完成后,需要将 node_modules/spire.office/lib 目录下的以下文件及文件夹复制到 React 项目的 public 文件夹中: spire.doc.js Spire.Doc.Wasm.zip spire.common.js Spire.Common.Wasm.zip _framework 文件夹 这些文件是 WASM 模块运行所必需的资源,放置在 public 目录下可以确保构建工具(如 Webpack)不会错误地处理它们,且能通过环境变量正确访问。 3. 准备静态资源 将项目需要用到的字体文件(如 times.ttf )和用于测试的 Word 文档(如 input.docx )分别放入 public/static/font/ 和 public/static/data/ 目录下。 三、WASM 模块加载(通用前置步骤) 所有转换功能都依赖于 WASM 模块的加载。以下代码展示了如何在 React 组件挂载时异步加载该模块,并将其挂载到 window 对象上以便全局调用: import React , { useState, useEffect } from 'react' ; function App ( ) { const [wasmModule, setWasmModule] = useState ( null ); useEffect ( () => { ( async () => { try { const publicUrl = process. env . PUBLIC_URL || '' ; const spireModule = await import ( /* webpackIgnore: true */ ` ${publicUrl} /spire.doc.js` ); const rawModule = spireModule. default || spireModule; // 初始化 WASM 模块并配置资源定位路径 window . wasmModule = typeof rawModule === 'function' ? await rawModule ({ locateFile : p => p. endsWith ( '.wasm' ) ? ` ${publicUrl} / ${p} ` : p }) : rawModule; setWasmModule ( module ); } catch (error) { console . error ( 'Failed to load WASM module:' , error); } })(); }, []); // 后续的转换函数将在此处定义... } 四、核心转换场景与配置详解 以下代码片段均省略了重复的字体加载和文件下载逻辑,以突出每种场景的核心配置。完整的下载逻辑可参考场景一的示例。 场景一:嵌入标准字体以保证跨设备一致性 当目标 PDF 需要在未安装对应字体的设备上打开时,应将字体文件嵌入 PDF。通过 IsEmbeddedAllFonts 参数即可实现: const convertWithEmbeddedFonts = async ( ) => { const doc = new window . wasmModule . spiredoc . Document (); doc. LoadFromFile ( 'input.docx' ); let parameters = new window . wasmModule . spiredoc . ToPdfParameterList (); parameters. IsEmbeddedAllFonts = true ; // 关键配置:嵌入所有字体 doc. SaveToFile ({ fileName : 'output.pdf' , paramList : parameters }); // ... 后续文件读取与下载 }; 场景二:适配非系统安装的特殊字体 对于系统未安装的第三方字体,可通过 PrivateFontPaths 指定字体文件路径,将其嵌入 PDF: const convertWithPrivateFonts = async ( ) => { const doc = new window . wasmModule . spiredoc . Document (); doc. LoadFromFile ( 'input.docx' ); let parameters = new window . wasmModule . spiredoc . ToPdfParameterList (); // 映射字体名称与 VFS 中的字体文件名 let fonts = new window . wasmModule . spiredoc . PrivateFontPath ( 'Freebrush Script' , 'FreebrushScriptPLng.ttf' ); parameters. PrivateFontPaths = fonts; doc. SaveToFile ({ fileName : 'output.pdf' , paramList : parameters }); }; 场景三:生成带访问权限控制的加密 PDF 通过配置 PdfSecurity 对象,可以为 PDF 设置打开密码和权限密码: const convertWithEncryption = async ( ) => { const doc = new window . wasmModule . spiredoc . Document (); doc. LoadFromFile ( 'input.docx' ); let parameters = new window . wasmModule . spiredoc . ToPdfParameterList (); // 参数:打开密码,权限密码,权限标志,加密位数 parameters. PdfSecurity . Encrypt ( 'open-psd' , 'permission-psd' , wasmModule. PdfPermissionsFlags . Default , wasmModule. PdfEncryptionKeySize . Key128Bit ); doc. SaveToFile ({ fileName : 'encrypted.pdf' , paramList : parameters }); }; 场景四:控制 PDF 中的超链接行为 若希望在生成的 PDF 中将超链接转换为纯文本,可设置 DisableLink 属性: const convertWithDisabledLinks = async ( ) => { const doc = new window . wasmModule . spiredoc . Document (); doc. LoadFromFile ( 'input.docx' ); let parameters = new window . wasmModule . spiredoc . ToPdfParameterList (); parameters. DisableLink = true ; // 禁用超链接 doc. SaveToFile ({ fileName : 'no_links.pdf' , paramList : parameters }); }; 场景五:保留 Word 书签作为 PDF 书签 对于包含书签的 Word 文档,可设置参数以在 PDF 中保留导航书签: const convertWithBookmarks = async ( ) => { const doc = new window . wasmModule . spiredoc . Document (); doc. LoadFromFile ( 'input.docx' ); let parameters = new window . wasmModule . spiredoc . ToPdfParameterList (); parameters. CreateWordBookmarks = true ; // 创建 PDF 书签 doc. SaveToFile ({ fileName : 'bookmarks.pdf' , paramList : parameters }); }; 场景六:调节 PDF 中的图片压缩质量 通过调整 JPEGQuality 属性(取值范围 0-100),可在图片清晰度与最终文件大小之间取得平衡: const convertWithImageQuality = async ( ) => { const doc = new window . wasmModule . spiredoc . Document (); doc. LoadFromFile ( 'input.docx' ); // 设置图片质量为 40% doc. JPEGQuality = 40 ; doc. SaveToFile ({ fileName : 'compressed.pdf' , fileFormat : window . wasmModule . spiredoc . FileFormat . PDF }); }; 五、配置参数对照表 功能分类 配置项 说明 字体处理 IsEmbeddedAllFonts = true 嵌入文档中使用的所有标准字体 字体处理 PrivateFontPaths 指定并嵌入非系统安装的第三方字体 文档安全 PdfSecurity.Encrypt() 设置用户密码和所有者密码 内容控制 DisableLink = true 禁用 PDF 中的超链接功能 内容控制 CreateWordBookmarks = true 将 Word 书签转换为 PDF 书签 图像优化 JPEGQuality = 40 调整 PDF 内图片的压缩质量 六、常见问题排查与建议 输出 PDF 出现乱码 :这是字体缺失导致的。请确认所有用到的字体文件均已通过 FetchFileToVFS 加载到 VFS 中。 WASM 模块加载失败 :检查 public 目录下的资源文件是否完整,以及 locateFile 回调函数中的路径配置是否正确。可利用浏览器开发者工具的 Network 面板进行排查。 内存占用问题 :WASM 操作均在内存中进行。处理大型文档时,务必在操作完成后调用 doc.Dispose() 手动释放资源,以避免内存泄漏。 用户体验优化 :考虑到 WASM 加载和文档处理需要一定时间,建议在 UI 中添加加载状态提示。 七、总结 本文介绍了一种在 React 应用中实现 Word 转 PDF 的纯前端技术方案。该方案基于 WebAssembly,通过虚拟文件系统在浏览器沙箱中完成文档处理,有效保障了数据隐私并降低了服务器开销。文章分别阐述了从字体嵌入、文档加密到内容控制、图像压缩等六种常见业务场景的配置方法。开发者可根据实际项目需求,灵活组合这些配置选项,构建出符合预期的文档转换功能。