Vue项目实现电子签名图片嵌入到pdf文件中并导出的方法

1. 前言:

  • 公司项目需要实现一个功能:将电子签名的图片嵌入到一个pdf文件中,然后导出
  • 思路:利用第三方插件pdf.lib实现

2. 实现思路

  1. 首先需要一个已知的pdf文件(转成ArrayBuffer类型),一个电子签名图片(转成Base64类型)
  2. 然后在vue项目中引入pdf.lib插件
  3. 先通过pdf.libload()方法读取pdf文件,通过embebPng()方法将图片嵌入到pdf文件中
  4. 然后利用drawImg()方法调整图片到指定为止
  5. 最后用save()方法生成处理好的pdf文件(此时是ArrayBuffer类型)
  6. 如果是需要下载处理好的文件,转成Blob类型然后实现下载
  7. 如果是传入后端接口,转成file类型用formData表单形式发送文件数据

3. 实现代码:

首先安装插件:npm install pdf-lib --save

typescript 复制代码
import { PDFDocument } from "pdf-lib";
import axios from "axios";

// 处理函数,注意处理文件是异步的,async/await 不能漏
async function handleSubmit() {
  // 1. 通过fetch请求拿到本地的拿到PDF文件
  const pdfResponse = await fetch("/example.pdf");
  // 2. 将pdf文件转成ArrayBuffer形式
  const pdfArrayBuffer = await pdfResponse.arrayBuffer();
  // 3. 拿到签名图片,这里的imgData就是png图片,要是Base64格式的
  const pngBase64 = imgData;
  // 4. 使用pdf.lib插件读取PDF文档
  const pdfDoc = await PDFDocument.load(pdfArrayBuffer);
  // 5. 将Base64格式的图片转成相应的png图片格式,如果要转成jpg的,改用`embebJpg()`方法
  const pngImage = await pdfDoc.embedPng(pngBase64);
  // 6. 读取PDF页数
  const pages = pdfDoc.getPages();
  // 7. 在PDF相应页码中绘制,这里是在第二页绘制
  pages[1].drawImage(pngImage, { x: 120, y: 80, width: pngImage.width / 20, height: pngImage.height / 20 });
  // 8. 处理完后,将数据另存为pdf文件(此时是ArrayBuffer格式)
  const pdfBytes = await pdfDoc.save();
  // 9. 这里是下载功能:ArrayBuffer 转 Blob 再转 File,然后生成下载链接
  const blob = new Blob([pdfBytes], { type: "application/pdf" });
  const file = new File([blob], "example.pdf", { type: "application/pdf" });
  // 10. 生成下载链接
  const url = URL.createObjectURL(blob);
  // 11. 触发下载
  const a = document.createElement("a");
  a.href = url;
  a.download = "example.pdf";
  document.body.appendChild(a);
  a.click();
  // 12. 释放 URL 对象
  URL.revokeObjectURL(url);
  document.body.removeChild(a);
  // 13. 这里是上传数据到服务器的方法:上传 PDF 文件
  const formData = new FormData();
  formData.append("file", file);
  // 14. 这里是接口的一个自定义参数biz,用来指定上传到哪个目录
  formData.append("biz", "report");
  // 15. 发送接口数据
  await axios({
	headers: {
	  "Content-Type": "multipart/form-data",
	},
	method: "POST",
	url: "http://example.com/upload",
	data: formData
  });
}
</script>
相关推荐
listhi52044 分钟前
利用React Hooks简化状态管理
前端·javascript·react.js
paopaokaka_luck1 小时前
基于SpringBoot+Vue的助农扶贫平台(AI问答、WebSocket实时聊天、快递物流API、协同过滤算法、Echarts图形化分析、分享链接到微博)
java·vue.js·spring boot·后端·websocket·spring
一点一木1 小时前
🚀 2025 年 10 月 GitHub 十大热门项目排行榜 🔥
前端·人工智能·github
华仔啊1 小时前
这个Vue3旋转菜单组件让项目颜值提升200%!支持多种主题,拿来即用
前端·javascript·css
非凡ghost2 小时前
Adobe Lightroom安卓版(手机调色软件)绿色版
前端·windows·adobe·智能手机·软件需求
Sheldon一蓑烟雨任平生2 小时前
Vue3 重构待办事项(主要练习组件化)
vue.js·重构·vue3·组件化练习
BestAns2 小时前
Postman 平替?这款轻量接口测试工具,本地运行 + 批量回归超实用!
前端
专注前端30年2 小时前
Webpack进阶玩法全解析(性能优化+高级配置)
前端·webpack·性能优化
烛阴3 小时前
Lua世界的基石:变量、作用域与七大数据类型
前端·lua
张拭心3 小时前
“不卷 AI、不碰币、下班不收消息”——Android 知名技术大牛 Jake Wharton 的求职价值观
android·前端·aigc