ASP.NET嵌入可填写PDF后,如何将用户填写内容上传至服务器
解决方案:ASP.NET中嵌入可编辑PDF表单并直接提交至服务器
浏览器内置PDF阅读器(iframe嵌入)受同源策略与安全限制,无法直接获取填充后的完整PDF内容,以下是两种可行的实现方案:
方案一:使用前端PDF处理库(推荐)
通过前端PDF库渲染可编辑表单、收集用户输入,再将字段数据提交到后端,由后端基于原始PDF模板生成填充后的文件并存入数据库。
步骤1:前端集成PDF.js渲染表单并收集数据
<div id="pdf-container" style="position: relative;"></div> <button id="submit-btn">提交表单</button> <script src="/js/pdf.min.js"></script> <script> let pdfDoc; const container = document.getElementById('pdf-container'); // 加载并渲染PDF模板 async function initPdf() { const pdfRes = await fetch('/Templates/EditableForm.pdf'); const pdfBuffer = await pdfRes.arrayBuffer(); pdfDoc = await pdfjsLib.getDocument({ data: pdfBuffer }).promise; // 渲染第一页(多页可循环处理) const page = await pdfDoc.getPage(1); const viewport = page.getViewport({ scale: 1.2 }); const canvas = document.createElement('canvas'); canvas.width = viewport.width; canvas.height = viewport.height; container.appendChild(canvas); await page.render({ canvasContext: canvas.getContext('2d'), viewport }).promise; // 生成对应HTML编辑控件 const formFields = await pdfDoc.getFieldObjects(); for (const [fieldName, field] of Object.entries(formFields)) { let input; switch (field.fieldType) { case 'Tx': // 文本框 input = document.createElement('input'); input.type = 'text'; input.name = fieldName; break; case 'Btn': // 复选框 input = document.createElement('input'); input.type = 'checkbox'; input.name = fieldName; break; // 可扩展下拉框、单选框等类型 } if (input) { input.style.position = 'absolute'; input.style.left = `${field.rect[0]}px`; input.style.top = `${field.rect[1]}px`; input.style.width = `${field.rect[2] - field.rect[0]}px`; container.appendChild(input); } } } // 提交数据到后端 document.getElementById('submit-btn').addEventListener('click', async () => { const fieldData = {}; container.querySelectorAll('input').forEach(input => { fieldData[input.name] = input.type === 'checkbox' ? input.checked : input.value; }); const res = await fetch('/api/Pdf/SaveFilledForm', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(fieldData) }); res.ok ? alert('提交成功') : alert('提交失败'); }); initPdf(); </script>
步骤2:ASP.NET后端填充PDF并保存到数据库
使用iTextSharp处理PDF模板,填充字段后将文件存入数据库。
首先安装NuGet包:Install-Package iTextSharp
示例后端API代码(ASP.NET Core):
using iTextSharp.text.pdf; using Microsoft.AspNetCore.Mvc; using System.IO; [ApiController] [Route("api/[controller]")] public class PdfController : ControllerBase { private readonly IWebHostEnvironment _env; public PdfController(IWebHostEnvironment env) { _env = env; } [HttpPost("SaveFilledForm")] public async Task<IActionResult> SaveFilledForm([FromBody] Dictionary<string, object> fieldData) { string templatePath = Path.Combine(_env.WebRootPath, "Templates", "EditableForm.pdf"); using var templateStream = new FileStream(templatePath, FileMode.Open); using var outputStream = new MemoryStream(); var reader = new PdfReader(templateStream); var stamper = new PdfStamper(reader, outputStream); var form = stamper.AcroFields; // 填充表单字段 foreach (var kvp in fieldData) { if (!form.Fields.ContainsKey(kvp.Key)) continue; if (kvp.Value is bool isChecked) { form.SetField(kvp.Key, isChecked ? "Yes" : "Off"); // 匹配PDF模板复选框的导出值 } else { form.SetField(kvp.Key, kvp.Value.ToString()); } } stamper.Close(); reader.Close(); // 将生成的PDF转为字节数组,存入数据库 byte[] pdfBytes = outputStream.ToArray(); // 替换为你的数据库操作逻辑 // await _dbContext.FilledPdfs.AddAsync(new FilledPdf { Data = pdfBytes, CreatedAt = DateTime.Now }); // await _dbContext.SaveChangesAsync(); return Ok(); } }
方案二:依赖Adobe Acrobat插件(兼容性有限)
仅在用户安装Adobe Acrobat插件时生效,通过PDF内部JS导出表单数据,传递给页面JS后提交到后端。但因插件普及率低,不推荐用于通用场景。
内容的提问来源于stack exchange,提问作者fake account
相关产品推荐
相关产品推荐

