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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 04:19:52