You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ionic 3应用集成PDF数字签名功能技术求助

Hey there! Let's tackle adding digital signature functionality to your Ionic 3 PDF viewer app. Here's a step-by-step solution tailored to your use case:

Step 1: Pick Compatible Libraries

Since Ionic 3 runs on Angular 5+, we'll use libraries that play nice with older Angular versions:

  • pdf-lib@1.17.1: For loading, modifying, and saving PDFs
  • signature_pad@2.3.2: For capturing user-drawn signatures

Install them via npm:

npm install pdf-lib@1.17.1 signature_pad@2.3.2 --save
npm install @types/signature_pad --save-dev
Step 2: Build a Signature Capture Component

First, create a reusable component to let users draw and confirm their signature.

Component Template (signature-capture.html)

<div class="signature-container">
  <canvas #signatureCanvas></canvas>
  <div class="signature-buttons">
    <button ion-button small (click)="clearSignature()">Clear</button>
    <button ion-button small primary (click)="confirmSignature()">Confirm</button>
  </div>
</div>

Component Styles (signature-capture.scss)

.signature-container {
  padding: 16px;
  canvas {
    border: 1px solid #ccc;
    width: 100%;
    height: 200px;
  }
  .signature-buttons {
    margin-top: 12px;
    display: flex;
    gap: 8px;
    justify-content: flex-end;
  }
}

Component Logic (signature-capture.ts)

import { Component, ViewChild, ElementRef, Output, EventEmitter } from '@angular/core';
import SignaturePad from 'signature_pad';

@Component({
  selector: 'signature-capture',
  templateUrl: 'signature-capture.html',
  styleUrls: ['signature-capture.scss']
})
export class SignatureCaptureComponent {
  @ViewChild('signatureCanvas') signatureCanvas: ElementRef;
  @Output() signatureConfirmed = new EventEmitter<string>();
  private signaturePad: SignaturePad;

  ngAfterViewInit() {
    this.signaturePad = new SignaturePad(this.signatureCanvas.nativeElement, {
      backgroundColor: '#ffffff',
      penColor: '#000000'
    });
  }

  clearSignature() {
    this.signaturePad.clear();
  }

  confirmSignature() {
    if (this.signaturePad.isEmpty()) {
      alert('Please draw your signature first!');
      return;
    }
    // Convert signature to base64 PNG for embedding
    const signatureDataUrl = this.signaturePad.toDataURL('image/png');
    this.signatureConfirmed.emit(signatureDataUrl);
  }
}
Step 3: Integrate Signature into Your PDF Viewer Page

Update your existing PDF view page to include a signature modal, then embed the signature into the PDF and save it.

Page Template (pdf-viewer.html)

<ion-header>
  <ion-navbar>
    <ion-title>View Document</ion-title>
    <ion-buttons end>
      <button ion-button (click)="openSignatureModal()">Add Signature</button>
    </ion-buttons>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <!-- Display original PDF via iframe -->
  <iframe [src]="pdfUrl" style="width: 100%; height: calc(100vh - 56px);"></iframe>
</ion-content>

<!-- Modal for signature capture -->
<ion-modal #signatureModal>
  <ion-header>
    <ion-navbar>
      <ion-title>Add Your Signature</ion-title>
      <ion-buttons end>
        <button ion-button (click)="signatureModal.dismiss()">Cancel</button>
      </ion-buttons>
    </ion-navbar>
  </ion-header>
  <ion-content>
    <signature-capture (signatureConfirmed)="handleSignatureConfirmed($event)"></signature-capture>
  </ion-content>
</ion-modal>

Page Logic (pdf-viewer.ts)

import { Component, ViewChild, OnInit } from '@angular/core';
import { PDFDocument } from 'pdf-lib';
import { File } from '@ionic-native/file';
import { FileOpener } from '@ionic-native/file-opener';

@Component({
  selector: 'pdf-viewer',
  templateUrl: 'pdf-viewer.html'
})
export class PdfViewerPage implements OnInit {
  @ViewChild('signatureModal') signatureModal;
  pdfUrl: string;
  originalPdfBytes: Uint8Array;
  documentId: string; // Pass this from your document list page

  constructor(
    private file: File,
    private fileOpener: FileOpener
  ) {}

  ngOnInit() {
    // Fetch your user's assigned PDF (replace with your actual API call)
    this.fetchAssignedPdf();
  }

  async fetchAssignedPdf() {
    const response = await fetch(`/api/user/documents/${this.documentId}`);
    this.originalPdfBytes = new Uint8Array(await response.arrayBuffer());
    // Create a blob URL to display the PDF in iframe
    const blob = new Blob([this.originalPdfBytes], { type: 'application/pdf' });
    this.pdfUrl = URL.createObjectURL(blob);
  }

  openSignatureModal() {
    this.signatureModal.present();
  }

  async handleSignatureConfirmed(signatureDataUrl: string) {
    this.signatureModal.dismiss();
    try {
      // Load the original PDF
      const pdfDoc = await PDFDocument.load(this.originalPdfBytes);
      // Embed the signature image into the PDF
      const signatureImage = await pdfDoc.embedPng(signatureDataUrl);
      const targetPage = pdfDoc.getPages()[0]; // Adjust index for your target page
      const { width, height } = targetPage.getSize();

      // Draw signature at bottom-right (adjust position/size as needed)
      targetPage.drawImage(signatureImage, {
        x: width - 200,
        y: 50,
        width: 180,
        height: 80
      });

      // Save the modified PDF
      const signedPdfBytes = await pdfDoc.save();
      await this.saveAndStoreSignedPdf(signedPdfBytes);
      alert('Signature added successfully!');
    } catch (error) {
      console.error('Error adding signature:', error);
      alert('Failed to add signature. Please try again.');
    }
  }

  async saveAndStoreSignedPdf(pdfBytes: Uint8Array) {
    // Save to device's document directory
    const fileName = `signed_${this.documentId}.pdf`;
    await this.file.writeFile(this.file.documentsDirectory, fileName, pdfBytes, { replace: true });

    // Optional: Open the signed PDF to confirm
    await this.fileOpener.open(
      `${this.file.documentsDirectory}/${fileName}`,
      'application/pdf'
    );

    // Optional: Upload signed PDF back to your server
    // this.uploadSignedPdfToServer(pdfBytes);
  }

  // uploadSignedPdfToServer(pdfBytes: Uint8Array) {
  //   const formData = new FormData();
  //   formData.append('signedPdf', new Blob([pdfBytes], { type: 'application/pdf' }), `signed_${this.documentId}.pdf`);
  //   // Add your API call here to send formData to your backend
  // }
}
Step 4: Set Up Required Plugins

For file handling and opening PDFs on the device, install these Ionic Native plugins:

ionic cordova plugin add cordova-plugin-file
npm install @ionic-native/file

ionic cordova plugin add cordova-plugin-file-opener2
npm install @ionic-native/file-opener

Don't forget to add them to your app.module.ts providers array.

Quick Tips
  • Signature Placement: Tweak the x, y, width, and height values in drawImage to position the signature exactly where you need it.
  • Legal Signatures: If you need legally binding signatures (not just image overlays), you'll need to integrate a certificate-based signing solution (like PKCS#12), but image-based signatures work great for internal workflows.
  • Testing: Test with your actual PDF documents to ensure compatibility with pdf-lib.

内容的提问来源于stack exchange,提问作者Vineet Chauhan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:23:46