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

如何用Node.js的pdf-lib将PDF指定文本替换为签名图片?

使用Node.js的pdf-lib替换PDF中指定文本为签名图片

需求:将名为offer_letter.pdf的PDF文件中的文本owner_sign替换为签名图片sign.png。

原代码存在的问题

  • 未定位owner_sign的实际位置,硬编码坐标可能与实际文本位置不符
  • 循环内重复嵌入签名图片,造成资源浪费
  • 变量page未定义,应使用pages[i]
  • 未覆盖原文本,直接叠加图片可能导致原文本仍可见

完整解决方案

由于pdf-lib本身不提供文本位置检索功能,需结合pdf-parse获取目标文本的坐标,再进行替换操作:

  1. 先安装依赖:
npm install pdf-lib pdf-parse
  1. 修正后的代码:
const { PDFDocument, StandardFonts, rgb } = require('pdf-lib');
const fs = require('fs');
const pdfParse = require('pdf-parse');

async function findTextPosition(pdfBuffer, targetText) {
  const data = await pdfParse(pdfBuffer);
  const pages = data.pages;
  const positions = [];
  for (let pageNum = 0; pageNum < pages.length; pageNum++) {
    const textItems = pages[pageNum].items;
    for (const item of textItems) {
      if (item.str.includes(targetText)) {
        positions.push({
          pageIndex: pageNum,
          x: item.x,
          y: item.y,
          width: item.width,
          height: item.height
        });
      }
    }
  }
  return positions;
}

async function modifyPdf() {
  try {
    // 读取源PDF和签名图片
    const pdfBytes = fs.readFileSync('offer_letter.pdf');
    const signatureImageBytes = fs.readFileSync('sign.png');
    const textToReplace = "owner_sign";

    // 查找目标文本位置
    const textPositions = await findTextPosition(pdfBytes, textToReplace);
    if (textPositions.length === 0) {
      console.log("未找到目标文本");
      return;
    }

    // 加载PDF文档
    const pdfDoc = await PDFDocument.load(pdfBytes);
    // 仅嵌入一次签名图片
    const signatureImage = await pdfDoc.embedPng(signatureImageBytes);
    const scaledImage = signatureImage.scale(0.5);
    const imageWidth = scaledImage.width;
    const imageHeight = scaledImage.height;

    // 遍历每个找到的文本位置进行替换
    for (const pos of textPositions) {
      const page = pdfDoc.getPages()[pos.pageIndex];
      // 用白色矩形覆盖原文本
      page.drawRectangle({
        x: pos.x,
        y: pos.y - pos.height, // 适配PDF坐标系(原点在左下角)
        width: pos.width,
        height: pos.height * 1.2, // 适当放大覆盖区域
        color: rgb(1, 1, 1) // 白色背景覆盖
      });
      // 在原文本位置绘制签名图片
      page.drawImage(signatureImage, {
        x: pos.x,
        y: pos.y - imageHeight,
        width: imageWidth,
        height: imageHeight
      });
    }

    // 保存修改后的PDF
    const modifiedPdfBytes = await pdfDoc.save();
    fs.writeFileSync('modified_offer_letter.pdf', modifiedPdfBytes);
    console.log("PDF修改完成");
  } catch (error) {
    console.error("处理出错:", error);
  }
}

modifyPdf();

关键说明

  • pdf-parse的文本坐标可能因PDF生成工具不同存在差异,若匹配不准确需调整坐标计算逻辑
  • PDF坐标系原点在左下角,绘制时需注意y轴坐标的转换
  • 若原文本有复杂格式(如不同字体、字号),需优化文本匹配和覆盖逻辑

内容的提问来源于stack exchange,提问作者HEMANT PATEL

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 03:57:05