当前位置:首页 > VUE

vue实现pdf签名

2026-02-17 23:28:33VUE

Vue 实现 PDF 签名功能

使用 pdf-lib 和 signature_pad 库

安装依赖库:

npm install pdf-lib signature_pad

创建签名画布组件:

<template>
  <div>
    <canvas ref="signatureCanvas" width="500" height="200"></canvas>
    <button @click="clearSignature">清除</button>
    <button @click="saveSignature">保存</button>
  </div>
</template>

<script>
import SignaturePad from 'signature_pad'

export default {
  data() {
    return {
      signaturePad: null
    }
  },
  mounted() {
    this.signaturePad = new SignaturePad(this.$refs.signatureCanvas)
  },
  methods: {
    clearSignature() {
      this.signaturePad.clear()
    },
    saveSignature() {
      const signatureData = this.signaturePad.toDataURL()
      this.$emit('signature-saved', signatureData)
    }
  }
}
</script>

将签名添加到 PDF

处理 PDF 文档:

vue实现pdf签名

import { PDFDocument, rgb } from 'pdf-lib'

async function addSignatureToPdf(pdfBytes, signatureImage) {
  const pdfDoc = await PDFDocument.load(pdfBytes)
  const pages = pdfDoc.getPages()
  const firstPage = pages[0]

  const pngImage = await pdfDoc.embedPng(signatureImage)
  const pngDims = pngImage.scale(0.5)

  firstPage.drawImage(pngImage, {
    x: 50,
    y: 50,
    width: pngDims.width,
    height: pngDims.height,
  })

  const modifiedPdfBytes = await pdfDoc.save()
  return modifiedPdfBytes
}

完整实现示例

主组件实现:

<template>
  <div>
    <input type="file" @change="handlePdfUpload" accept=".pdf" />
    <signature-pad v-if="pdfFile" @signature-saved="handleSignatureSave" />
    <button v-if="signedPdf" @click="downloadSignedPdf">下载签名PDF</button>
  </div>
</template>

<script>
import SignaturePad from './SignaturePad.vue'
import { addSignatureToPdf } from './pdf-utils'

export default {
  components: {
    SignaturePad
  },
  data() {
    return {
      pdfFile: null,
      signedPdf: null
    }
  },
  methods: {
    async handlePdfUpload(event) {
      this.pdfFile = event.target.files[0]
    },
    async handleSignatureSave(signatureData) {
      const arrayBuffer = await this.pdfFile.arrayBuffer()
      const signedPdfBytes = await addSignatureToPdf(arrayBuffer, signatureData)
      this.signedPdf = new Blob([signedPdfBytes], { type: 'application/pdf' })
    },
    downloadSignedPdf() {
      const url = URL.createObjectURL(this.signedPdf)
      const link = document.createElement('a')
      link.href = url
      link.download = 'signed-document.pdf'
      link.click()
    }
  }
}
</script>

其他注意事项

签名画布样式需要适当调整以确保清晰度:

vue实现pdf签名

canvas {
  border: 1px solid #000;
  background-color: #f8f8f8;
}

对于移动端支持,需要添加触摸事件处理:

mounted() {
  this.signaturePad = new SignaturePad(this.$refs.signatureCanvas, {
    onEnd: () => {
      this.$emit('signature-changed', this.signaturePad.isEmpty())
    }
  })
  this.setupCanvasScaling()
},
methods: {
  setupCanvasScaling() {
    const canvas = this.$refs.signatureCanvas
    function resizeCanvas() {
      const ratio = Math.max(window.devicePixelRatio || 1, 1)
      canvas.width = canvas.offsetWidth * ratio
      canvas.height = canvas.offsetHeight * ratio
      canvas.getContext('2d').scale(ratio, ratio)
      this.signaturePad.clear() // 防止缩放后签名变形
    }
    window.addEventListener('resize', resizeCanvas)
    resizeCanvas()
  }
}

替代方案考虑

对于更复杂的需求,可以考虑使用专业PDF库:

  • PSPDFKit:商业解决方案,功能全面
  • PDF.js:Mozilla开源项目,适合查看和简单注释
  • jsPDF:生成PDF而非编辑现有PDF

以上实现提供了在Vue应用中实现PDF签名的基本流程,可根据具体需求调整签名位置、大小和样式。

标签: vuepdf
分享给朋友:

相关文章

vue实现安全免登录

vue实现安全免登录

Vue 实现安全免登录的方案 免登录功能通常通过持久化认证状态(如 Token)实现,但需兼顾安全性。以下是基于 Vue 的常见实现方案: 基于 Token 的免登录 登录成功后存储 Token…

vue筛选实现

vue筛选实现

Vue 筛选实现方法 使用计算属性实现筛选 计算属性是 Vue 中实现数据筛选的常用方式。通过定义一个计算属性,可以根据输入的条件动态过滤数据。 <template> <div…

vue实现验证

vue实现验证

Vue 表单验证实现方法 在Vue中实现表单验证可以通过多种方式完成,以下是常见的几种方法: 使用Vuelidate库 Vuelidate是一个轻量级的Vue表单验证库,安装后可以通过简单的配置实现…

vue删除实现

vue删除实现

Vue 删除功能的实现方法 在 Vue 中实现删除功能通常涉及以下几个步骤: 方法一:使用数组的 splice 方法 通过索引删除数组中的元素,适用于列表渲染的场景。 methods: {…

vue sku 实现

vue sku 实现

Vue SKU 实现方案 在电商系统中,SKU(Stock Keeping Unit)是商品的最小库存单位,通常由多个属性组合而成(如颜色、尺寸等)。以下是基于 Vue 的实现方案。 数据结构设计…

实现vue vm

实现vue vm

Vue VM 实现方法 Vue VM(ViewModel)是 Vue.js 的核心概念之一,负责连接视图(View)和数据模型(Model)。以下是实现 Vue VM 的几种方法: 使用 Vue 实…