当前位置:首页 > 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
分享给朋友:

相关文章

jquery实现vue

jquery实现vue

jQuery 和 Vue.js 是两种不同理念的前端工具,jQuery 以 DOM 操作和事件驱动为核心,而 Vue.js 是数据驱动的现代化框架。如果想用 jQuery 实现类似 Vue 的功能(如…

vue实现getapp

vue实现getapp

Vue 中实现全局获取应用实例的方法 在 Vue 3 中,可以通过 getCurrentInstance 方法获取当前组件实例,但需要明确其使用场景和限制。以下是具体实现方式: 方法一:通过 get…

vue实现布局

vue实现布局

Vue 实现布局方法 Vue 提供了多种方式实现页面布局,可以通过组件化、CSS 框架或自定义样式完成。以下是几种常见方法: 使用 CSS Flexbox 或 Grid 通过 Vue 单文件组件结合…

vue实现keepalive

vue实现keepalive

Vue 中实现 keep-alive 在 Vue 中,keep-alive 是一个内置组件,用于缓存动态组件或组件的状态,避免重复渲染和销毁。以下是实现 keep-alive 的几种方法: 基本用法…

vue router实现分页

vue router实现分页

Vue Router 实现分页的方法 在 Vue.js 中,可以通过 Vue Router 实现分页功能,通常需要结合路由参数和动态路由匹配。以下是几种常见的实现方式: 使用查询参数实现分页 在路由…

vue实现弹层

vue实现弹层

Vue 实现弹层的方法 使用 Vue 原生组件实现弹层 创建一个基础的弹层组件,利用 v-if 或 v-show 控制显示隐藏。 <template> <div class="…