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

打印Base64格式PDF文档时触发‘参数无效’错误求助

打印Base64 PDF时“参数无效”错误的排查与解决

问题场景

尝试使用以下C#代码打印Base64格式转换而来的PDF文档,触发打印任务时出现“参数无效”错误,怀疑是未配置RenderEvents导致,但不确定具体原因。

原代码:

try
{
    using (var memoryStream = new MemoryStream(pdfBytes))
    {
        // Load the PDF document
        PdfSharp.Pdf.PdfDocument pdfDocument = PdfReader.Open(memoryStream, PdfDocumentOpenMode.ReadOnly);

        // Print each page
        for (int i = 0; i < pdfDocument.PageCount; i++)
        {
            using (var printDocument = new PrintDocument())
            {
                printDocument.PrinterSettings.PrinterName = printerName;

                // Handle the PrintPage event
                printDocument.PrintPage += (sender, e) =>
                        {
                            PdfSharp.Events.RenderEvents renderEvents = new PdfSharp.Events.RenderEvents();
                            XGraphics graphics = XGraphics.FromGraphics(e.Graphics, new XSize(e.MarginBounds.Width, e.MarginBounds.Height), renderEvents);

                            // Get the current page to print
                            var page = pdfDocument.Pages[i];
                            var pageWidth = page.Width;
                            var pageHeight = page.Height;

                            // Calculate the scale to fit the page
                            var scaleX = e.MarginBounds.Width / pageWidth;
                            var scaleY = e.MarginBounds.Height / pageHeight;
                            var scale = Math.Min(scaleX, scaleY);

                            // Center the page on the printer
                            var xPos = e.MarginBounds.Left + (e.MarginBounds.Width - (pageWidth * scale)) / 2;
                            var yPos = e.MarginBounds.Top + (e.MarginBounds.Height - (pageHeight * scale)) / 2;

                            // Draw the content of the PDF page
                            XImage xImage = XImage.FromStream(memoryStream);
                            graphics.DrawImage(xImage, xPos, yPos, pageWidth * scale, pageHeight * scale);

                            // Draw rectangle for the page border
                            graphics.DrawRectangle(XPens.Black, xPos, yPos, pageWidth * scale, pageHeight * scale);
                };

                // Trigger the print job
                printDocument.Print();
            }
        }
    }
}
catch (Exception ex)
{
    // 异常捕获
}

排查与解决建议

1. 核心问题:MemoryStream 位置与使用错误

  • 第一次用memoryStream加载PDF后,流的指针已移动到末尾,后续调用XImage.FromStream(memoryStream)时,流中无可读数据,直接触发“参数无效”错误。
  • 另外,XImage.FromStream无法直接从整个PDF流中提取单页图像,属于用法错误。

2. 正确渲染方式:直接绘制PDF页面

无需将PDF转成XImage,直接使用PdfPage.Draw方法将页面渲染到XGraphics上,这是PdfSharp官方推荐的打印方式。

3. RenderEvents 不是问题根源

RenderEvents是可选参数,默认构造即可,不会引发“参数无效”错误,可保留或直接省略(XGraphics.FromGraphics有重载不需要该参数)。

修正后的代码

try
{
    using (var memoryStream = new MemoryStream(pdfBytes))
    {
        PdfSharp.Pdf.PdfDocument pdfDocument = PdfReader.Open(memoryStream, PdfDocumentOpenMode.ReadOnly);

        for (int i = 0; i < pdfDocument.PageCount; i++)
        {
            using (var printDocument = new PrintDocument())
            {
                printDocument.PrinterSettings.PrinterName = printerName;
                int currentPage = i; // 捕获循环变量,避免闭包问题

                printDocument.PrintPage += (sender, e) =>
                {
                    // 省略RenderEvents,使用重载方法
                    XGraphics graphics = XGraphics.FromGraphics(e.Graphics, new XSize(e.MarginBounds.Width, e.MarginBounds.Height));
                    var page = pdfDocument.Pages[currentPage];
                    var pageWidth = page.Width;
                    var pageHeight = page.Height;

                    // 计算缩放比例和位置
                    var scaleX = e.MarginBounds.Width / pageWidth;
                    var scaleY = e.MarginBounds.Height / pageHeight;
                    var scale = Math.Min(scaleX, scaleY);
                    var xPos = e.MarginBounds.Left + (e.MarginBounds.Width - pageWidth * scale) / 2;
                    var yPos = e.MarginBounds.Top + (e.MarginBounds.Height - pageHeight * scale) / 2;

                    // 直接绘制PDF页面
                    graphics.ScaleTransform(scale);
                    graphics.TranslateTransform(xPos / scale, yPos / scale);
                    page.Draw(graphics);

                    // 绘制页面边框(可选)
                    graphics.DrawRectangle(XPens.Black, 0, 0, pageWidth, pageHeight);
                };

                printDocument.Print();
            }
        }
    }
}
catch (Exception ex)
{
    // 处理异常
}

额外注意点

  • 闭包问题:原代码直接在事件处理中使用循环变量i,会导致所有打印任务都使用最后一次循环的i值,需将i赋值给局部变量currentPage再捕获。
  • 流的复用:若需多次读取流,每次读取前要调用memoryStream.Seek(0, SeekOrigin.Begin)重置指针,但本方案无需此操作,直接通过pdfDocument.Pages访问页面即可。

内容的提问来源于stack exchange,提问作者innom

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 17:31:01