SelectPDF转MemoryStream时丢失Acroform表单字段数据求助
问题:填充AcroForm字段后打印无数据(SelectPDF场景)
- 本地加载PDF表单模板,通过SelectPDF的
PdfFormManager填充AcroForm字段,转MemoryStream打印后,输出的表单没有新填充的数据 - 直接加载已保存填充数据的PDF文件打印(手动/代码方式)均正常
- 业务要求:从数据库取数填充后直接打印,禁止保存到本地
- 已尝试无效操作:打印前断开表单与MemoryStream的连接、先转
byte[]再转MemoryStream;查Stack Overflow无匹配案例,联系SelectPDF官方支持未获回复
相关代码
private void TestSearchReplace() { try { // Form template string file = @"C:\CodeBackups\WinLossWeb\WinLossWeb_SelectPDF\w-9.pdf"; // load the pdf form manager PdfFormManager form = new PdfFormManager(); form.Load(file); // fill some fields PdfFormFieldTextBox name = form.Fields["f1_1"] as PdfFormFieldTextBox; name.Text = "This is my name"; PdfFormFieldTextBox businessName = form.Fields["f1_2"] as PdfFormFieldTextBox; businessName.Text = "This is my business name"; PdfFormFieldCheckBox clasifIndividual = form.Fields["c1_1"] as PdfFormFieldCheckBox; clasifIndividual.Checked = true; PdfFormFieldTextBox address = form.Fields["f1_7"] as PdfFormFieldTextBox; address.Text = "This is my address"; PdfFormFieldTextBox city = form.Fields["f1_8"] as PdfFormFieldTextBox; city.Text = "This is my city"; PdfFormFieldTextBox employer1 = form.Fields["f1_14"] as PdfFormFieldTextBox; employer1.Text = "XX"; PdfFormFieldTextBox employer2 = form.Fields["f1_15"] as PdfFormFieldTextBox; employer2.Text = "1234567"; PdfFormFieldTextBox ssn1 = form.Fields["f1_11"] as PdfFormFieldTextBox; ssn1.Text = "123"; PdfFormFieldTextBox ssn2 = form.Fields["f1_12"] as PdfFormFieldTextBox; ssn2.Text = "45"; PdfFormFieldTextBox ssn3 = form.Fields["f1_13"] as PdfFormFieldTextBox; ssn3.Text = "6789"; var streamPDF = new MemoryStream(form.Save()); // form.Close(); PrintPDF(streamPDF); } catch(Exception ex) { _logger.Log(LogLevel.Error, ex.Message + " In WinLossByPlayerID.TestSerachReplace"); }; } public void PrintPDF(MemoryStream docStream) { // instantiate PDF printer class PdfPrinter printer = new PdfPrinter(); printer.Load(docStream); // set event handlers for before/after printing of each page printer.BeforePagePrinting += Printer_BeforePagePrinting; printer.AfterPagePrinting += Printer_AfterPagePrinting; // set first page to be printed (default value 1) printer.StartPageNumber = 1; // set the last page to be printed // (default value 0 - all pages are printed, starting with first page specified) printer.EndPageNumber = 0; // set color space printer.ColorSpace = PdfRasterizerColorSpace.RGB; // set silent printing printer.ShowPrintProgress = false; // the document name to display (for example, in a print status dialog box or printer queue) while printing the document printer.DocumentName = "winlossTEST_Document.pdf"; // select printer printer.PrinterSettings.PrinterName = "Data Center"; printer.PrinterSettings.PrintFileName = "WinlossPrintToPDF.pdf"; // set page size (specify paper size name, width and height in points) printer.PageSettings.PaperSize = new PaperSize("A4", 826, 1169); // set page orientation (default Portrait) printer.PageSettings.Landscape = false; // set margins printer.PageSettings.Margins = new Margins(0, 0, 0, 0); // print PDF document printer.Print(); } // this is called before each page printing private static void Printer_BeforePagePrinting(object sender, PdfPrinterBeforePagePrintingEventArgs args) { Console.WriteLine("Preparing to print page " + args.PageNumber + ": " + args.PageSize.Width + "x" + args.PageSize.Height); // cancel printing process before starting printing page 3 if (args.PageNumber == 3) { args.Cancel = true; Console.WriteLine("Canceled before printing page " + args.PageNumber); } } // this is call after each page printing private static void Printer_AfterPagePrinting(object sender, PdfPrinterAfterPagePrintingEventArgs args) { Console.WriteLine("Printed page " + args.PageNumber); }
解决方案
1. 重置MemoryStream读取位置
创建MemoryStream后,流的指针默认处于末尾位置,PdfPrinter.Load无法读取到内容,需手动重置到起始处:
var streamPDF = new MemoryStream(form.Save()); streamPDF.Position = 0; // 关键步骤:将流指针移到开头 PrintPDF(streamPDF);
2. 扁平化表单字段
SelectPDF填充的AcroForm字段默认是可编辑状态,部分打印场景无法识别动态字段,需转为静态内容:
// 所有字段填充完成后调用 form.FlattenFields(); // 将表单字段转为静态文本/图形,避免打印丢失 var streamPDF = new MemoryStream(form.Save()); streamPDF.Position = 0; PrintPDF(streamPDF);
3. 正确释放表单资源
生成PDF字节流后,显式关闭PdfFormManager避免资源锁定:
var pdfBytes = form.Save(); form.Close(); // 释放表单管理器资源 var streamPDF = new MemoryStream(pdfBytes); streamPDF.Position = 0; PrintPDF(streamPDF);
4. 用PdfDocument中转处理
如果上述方法无效,可尝试通过PdfDocument重新加载填充后的PDF,确保内容正确序列化:
var pdfBytes = form.Save(); form.Close(); using (var doc = new PdfDocument(pdfBytes)) { using (var tempStream = new MemoryStream()) { doc.Save(tempStream); tempStream.Position = 0; PrintPDF(tempStream); } }
内容的提问来源于stack exchange,提问作者Doug
相关产品推荐
相关产品推荐

