React Native中如何将react-native-signature-capture签名添加至PDF并保存?
实现React Native签名添加到PDF并保存的方案
当然可行!完全不需要用截图这种不够优雅的方式,咱们可以直接利用react-native-signature-capture生成的原生签名数据,把它嵌入到PDF里,再完成保存。下面给你一步步拆解实现方案:
一、获取原生签名数据(非截图)
react-native-signature-capture本身就支持导出签名的Base64编码图片数据,这比截图的质量更高,也更适合后续的PDF嵌入操作。你可以通过组件的onSaveEvent回调拿到这个数据:
import SignatureCapture from 'react-native-signature-capture'; // 在你的组件中使用 <SignatureCapture style={{ flex: 1 }} onSaveEvent={(result) => { // result.signature 就是签名的Base64字符串(不带data:image/png;base64,前缀) this.handleSignatureData(result.signature); }} onDragEvent={() => { /* 可选:签名绘制中的回调 */ }} saveImageFileInExtStorage={false} // 不需要存在外部存储,我们自己处理 />
二、将签名嵌入PDF
推荐使用react-native-pdf-lib这个库来处理PDF的创建和编辑,它支持直接将Base64图片插入到PDF的指定位置。
1. 安装依赖
npm install react-native-pdf-lib --save # 或者用yarn yarn add react-native-pdf-lib
(注意:按照库的官方说明完成iOS/Android的原生配置,比如iOS的Pod安装和Android的权限配置)
2. 嵌入签名到新PDF
如果是创建一份全新的带签名的PDF,可以参考这段代码:
import { PDFDocument, Page, Image } from 'react-native-pdf-lib'; import { Platform } from 'react-native'; async function createSignedPdf(base64Signature) { // 创建一个新的PDF文档 const pdfDoc = await PDFDocument.create(); // 添加一个空白页面(可以设置页面尺寸,比如A4) const page = await Page.create(PageSize.A4); // 将Base64签名转为PDF可识别的Image对象 // 注意:如果你的Base64带了data:image/png;base64,前缀,需要先去掉 const cleanBase64 = base64Signature.startsWith('data:') ? base64Signature.split(',')[1] : base64Signature; const signatureImage = await Image.fromBase64(cleanBase64); // 在页面的指定位置绘制签名,这里示例放在右下角 page.drawImage(signatureImage, { x: PageSize.A4.width - 180, // 横坐标,距离右侧30单位 y: 30, // 纵坐标,距离底部30单位 width: 150, // 签名宽度 height: 50, // 签名高度 }); // 将页面添加到文档 await pdfDoc.addPage(page); // 保存PDF到应用的私有文档目录 const savePath = await pdfDoc.save('signed_document.pdf'); return savePath; }
3. 嵌入签名到已有PDF
如果需要给一份已存在的PDF添加签名,代码可以调整为:
import { PDFDocument, Image } from 'react-native-pdf-lib'; async function addSignatureToExistingPdf(base64Signature, existingPdfPath) { // 打开已有的PDF文档 const pdfDoc = await PDFDocument.open(existingPdfPath); // 获取要添加签名的页面(这里取第一页,索引从0开始) const pages = await pdfDoc.getPages(); const targetPage = pages[0]; // 处理Base64签名并转为Image对象 const cleanBase64 = base64Signature.startsWith('data:') ? base64Signature.split(',')[1] : base64Signature; const signatureImage = await Image.fromBase64(cleanBase64); // 在目标页面绘制签名 targetPage.drawImage(signatureImage, { x: 200, y: 50, width: 150, height: 50, }); // 保存修改后的PDF(可以覆盖原文件,或者指定新文件名) const savedPath = await pdfDoc.save('signed_existing_document.pdf'); return savedPath; }
三、将PDF保存到可访问的位置
上面的代码会把PDF存在应用的私有目录里,如果需要让用户在系统文件管理器中能找到这份文档,可以配合react-native-fs将文件复制到公共存储目录:
1. 安装react-native-fs
npm install react-native-fs --save
2. 复制到公共目录的代码
import RNFS from 'react-native-fs'; import { Platform } from 'react-native'; async function copyToPublicStorage(privatePdfPath) { // 确定公共存储路径 const publicDir = Platform.OS === 'ios' ? RNFS.DocumentDirectoryPath // iOS的文档目录,用户可在文件APP中访问 : RNFS.ExternalStorageDirectoryPath; // Android的外部存储根目录 const targetPath = `${publicDir}/我的签名文档.pdf`; // 复制文件 await RNFS.copyFile(privatePdfPath, targetPath); // Android需要通知媒体库刷新,否则刚保存的文件可能不显示 if (Platform.OS === 'android') { await RNFS.scanFile(targetPath); } return targetPath; }
这样操作下来,你就可以完美实现“生成签名→嵌入PDF→保存文档”的全流程,完全不需要依赖截图,既保证了签名的清晰度,也符合专业文档处理的需求。
内容的提问来源于stack exchange,提问作者Leandro Villalobos




