如何在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
相关产品推荐
相关产品推荐

