当前位置:首页 > 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 中实现循环 Vue 提供了 v-for 指令用于实现循环渲染列表数据。v-for 可以遍历数组、对象或数字范围,生成动态的 DOM 元素。 遍历数组 使用 v-for 遍历数组时,语法…

vue的实现

vue的实现

Vue 的实现原理 Vue 是一个渐进式 JavaScript 框架,其核心实现主要包括响应式系统、虚拟 DOM、模板编译和组件化机制。以下是 Vue 实现的主要技术细节。 响应式系统 Vue 的…

vue实现单据

vue实现单据

Vue 实现单据功能的方法 使用 Vue 实现单据功能通常涉及表单设计、数据绑定、验证和提交等环节。以下是具体实现方案: 表单设计与数据绑定 使用 Vue 的 v-model 指令实现表单数据的双…

vue 实现轮播

vue 实现轮播

Vue 实现轮播的方法 使用第三方库(如 Swiper) 安装 Swiper 库: npm install swiper 在 Vue 组件中引入 Swiper: <template&…

vue如何实现

vue如何实现

Vue 实现方法 在 Vue 中实现功能通常涉及组件化开发、状态管理和响应式数据绑定。以下是几种常见的实现方式: 组件化开发 使用 Vue 的单文件组件(.vue 文件)结构,将 UI 拆分为可复用…

vue 实现评分

vue 实现评分

Vue 实现评分功能 在 Vue 中实现评分功能可以通过多种方式完成,包括使用第三方组件库或自定义实现。以下是两种常见的方法: 使用第三方组件库(如 Element UI) Element UI…