在现代Web开发中,经常需要生成动态的PDF表单供用户填写并提交。本文将介绍如何使用C#和Visual Studio创建一个Web服务来动态生成PDF表单,并处理用户的提交。
要实现此功能,需要以下工具和环境:
如果还没有DotPdf库,可以从下载安装程序。
在Visual Studio中创建一个新的ASP.NET Web应用程序项目,并添加一个HTML页面和一个名为PdfHandler.ashx的通用处理程序。HTML页面将作为应用程序的起始页面,而PdfHandler.ashx将包含所有后端代码。
使用DotPdf库中的PdfGeneratedDocument类来生成PDF表单。以下是初始化文档并添加一个页面和表单的代码示例:
PdfGeneratedDocument doc = new PdfGeneratedDocument();
doc.Form = new Atalasoft.PdfDoc.Generating.Forms.PdfForm();
PdfPage page = doc.AddPage(PdfDefaultPages.Letter);
接下来,将创建一个文本字段供用户提交文本数据。这可以通过TextWidgetAnnotation类来实现,并使用PdfTextLine类来标记该字段。
TextWidgetAnnotation name = new TextWidgetAnnotation(
new PdfBounds(72, 700, 200, 20),
"name",
null
);
PdfTextLine nameLabel = new PdfTextLine(
"Helvetica",
22.0,
"Name:",
new PdfPoint(72, 730)
);
创建对象后,需要将它们添加到适当的渲染列表中。PdfTextLine需要添加到页面的绘图列表中,而TextWidgetAnnotation作为注释和表单的一部分,需要添加到注释列表和表单对象中。
page.DrawingList.Add(nameLabel);
page.Annotations.Add(name);
doc.Form.Fields.Add(name);
表单的另一个元素是提交按钮。当用户点击提交按钮时,希望PDF表单向Web处理程序发送POST请求。
PushButtonWidgetAnnotation button = new PushButtonWidgetAnnotation(
new PdfBounds(72, 550, 60, 20),
"submit"
);
PdfSubmitFormAction submit = new PdfSubmitFormAction(context.Request.Url);
submit.SubmitAsHtml = true;
button.ClickActions.Add(submit);
page.Annotations.Add(button);
doc.Form.Fields.Add(button);
建议将所有PDF生成代码封装在CreatePdf(context)方法调用中。
要将生成的PDF流式传输到客户端,需要将文档输出到Context.Response.OutputStream。以下是允许文档流式传输到客户端并在Adobe插件或Chrome的PDF查看器中自动打开的代码:
private void SendPdfForm(HttpContext context)
{
context.Response.Clear();
context.Response.ContentType = "application/pdf";
context.Response.AddHeader("Content-Disposition", "inline; filename=PDFForm");
PdfGeneratedDocument doc = CreatePdf(context);
MemoryStream mem = new MemoryStream();
doc.Save(mem);
mem.Seek(0, SeekOrigin.Begin);
byte[] pdfBytes = new byte[mem.Length];
mem.Read(pdfBytes, 0, (int)(mem.Length));
context.Response.AddHeader("Content-Length", pdfBytes.Length.ToString());
context.Response.BinaryWrite(pdfBytes);
context.Response.Flush();
context.Response.End();
}
在ashx文件中,生成时会有一个ProcessRequest方法的桩。所有对PdfHandler.ashx的请求都将路由到此方法。由于应用程序的性质,处理程序将收到两种不同的请求:一种是请求程序生成的PDF,另一种是处理PDF表单提交。
if (context.Request.InputStream.Length != 0)
HandleFormSubmission(context);
要区分PDF请求,可以通过查询字符串访问隐藏表单值:
if (context.Request.QueryString["pdf"] != null)
SendPdfForm(context);
在HTML文档中,向服务器请求动态生成的PDF非常简单。创建一个HTML表单,其中包含一个提交按钮和一个隐藏的数据值(这将作为查询字符串被消耗):
<form action="PdfHandler.ashx">
<input type="hidden" name="pdf" value="request" />
<input type="submit" id="Button1" value="Get Pdf Form" />
</form>
如果在这一点上调试应用程序,可以在ProcessRequest方法中的SendPdfForm方法调用处设置一个断点。如果在HTML页面上按下按钮,应该会触发断点。继续后,应该会看到一个PDF文档(假设使用的是Chrome或已安装并集成到浏览器中的Adobe Acrobat)。