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

如何在React应用中通过拖拽为上传PDF添加文本框(基于DocuSign API)

在React应用中使用DocuSign API实现PDF拖拽添加文本框功能

1. 完成DocuSign基础配置

  • 先在DocuSign开发者平台创建集成,获取集成密钥和OAuth2凭据,确保应用能获取有效访问令牌。
  • 安装官方SDK包初始化客户端:
    npm install docusign-esign
    

2. 搭建PDF预览与拖拽画布

用react-pdf渲染PDF,叠加透明画布层监听拖拽事件,实现文本框的可视化拖拽:

import { Document, Page } from 'react-pdf';
import { useState } from 'react';

function PdfFieldEditor() {
  const [pdfFile, setPdfFile] = useState(null);
  const [pageNumber, setPageNumber] = useState(1);
  const [dragStart, setDragStart] = useState(null);
  const [tempBox, setTempBox] = useState(null);
  const [savedFields, setSavedFields] = useState([]);

  // 处理PDF上传
  const handleFileUpload = (e) => {
    setPdfFile(URL.createObjectURL(e.target.files[0]));
  };

  // 拖拽开始:记录起始坐标
  const handleMouseDown = (e) => {
    const canvasRect = e.currentTarget.getBoundingClientRect();
    setDragStart({
      x: e.clientX - canvasRect.left,
      y: e.clientY - canvasRect.top,
      page: pageNumber
    });
  };

  // 拖拽过程:实时更新临时文本框
  const handleMouseMove = (e) => {
    if (!dragStart) return;
    const canvasRect = e.currentTarget.getBoundingClientRect();
    setTempBox({
      x: Math.min(dragStart.x, e.clientX - canvasRect.left),
      y: Math.min(dragStart.y, e.clientY - canvasRect.top),
      width: Math.abs(e.clientX - canvasRect.left - dragStart.x),
      height: 24, // 固定文本框高度,可自定义
      page: dragStart.page
    });
  };

  // 拖拽结束:保存文本框信息
  const handleMouseUp = () => {
    if (tempBox) {
      setSavedFields([...savedFields, tempBox]);
      setDragStart(null);
      setTempBox(null);
    }
  };

  return (
    <div>
      <input type="file" accept=".pdf" onChange={handleFileUpload} />
      {pdfFile && (
        <div style={{ position: 'relative', width: '800px', margin: '0 auto' }}>
          <Document file={pdfFile}>
            <Page pageNumber={pageNumber} />
          </Document>
          {/* 拖拽交互画布 */}
          <div
            style={{
              position: 'absolute',
              top: 0,
              left: 0,
              width: '100%',
              height: '100%',
              cursor: 'crosshair'
            }}
            onMouseDown={handleMouseDown}
            onMouseMove={handleMouseMove}
            onMouseUp={handleMouseUp}
            onMouseLeave={handleMouseUp}
          >
            {/* 临时拖拽框 */}
            {tempBox && (
              <div
                style={{
                  position: 'absolute',
                  left: tempBox.x,
                  top: tempBox.y,
                  width: tempBox.width,
                  height: tempBox.height,
                  border: '1px dashed #007bff',
                  backgroundColor: 'rgba(0,123,255,0.1)'
                }}
              />
            )}
            {/* 已保存的文本框 */}
            {savedFields.map((field, idx) => (
              <div
                key={idx}
                style={{
                  position: 'absolute',
                  left: field.x,
                  top: field.y,
                  width: field.width,
                  height: field.height,
                  border: '1px solid #007bff',
                  backgroundColor: 'rgba(0,123,255,0.05)'
                }}
              />
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

3. 转换坐标并调用DocuSign API添加字段

DocuSign以PDF页面左下角为坐标原点,需转换画布坐标后调用API添加文本字段:

import docusign from 'docusign-esign';

const addTextFieldsToEnvelope = async (envelopeId, savedFields, pageHeight) => {
  const apiClient = new docusign.ApiClient();
  apiClient.setBasePath('https://demo.docusign.net/restapi'); // 测试环境,生产环境替换为正式域名
  apiClient.addDefaultHeader('Authorization', `Bearer ${yourAccessToken}`);

  const envelopeApi = new docusign.EnvelopesApi(apiClient);
  // 转换为DocuSign要求的字段格式
  const textTabs = savedFields.map(field => ({
    documentId: '1', // 信封内PDF的文档ID,默认是1
    pageNumber: field.page.toString(),
    xPosition: field.x.toString(),
    yPosition: (pageHeight - field.y - field.height).toString(), // 转换为左下角原点坐标
    width: field.width.toString(),
    height: field.height.toString(),
    tabLabel: `text_field_${Date.now()}_${Math.random()}`,
    value: '' // 默认空值,可设置预设文本
  }));

  const tabs = { textTabs };
  await envelopeApi.createTabs('your_account_id', envelopeId, { tabs });
};

注:pageHeight可通过react-pdf的getDocument方法获取PDF页面实际高度。

4. 关键注意事项

  • 确保PDF上传后已创建DocuSign信封,documentId需与API调用中的值一致。
  • 处理PDF缩放时,要将画布坐标按缩放比例转换为实际PDF坐标,避免字段位置偏移。
  • 生产环境必须使用正式OAuth2流程获取访问令牌,禁止硬编码密钥。

内容的提问来源于stack exchange,提问作者Anonymous React

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:58:13