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

C#如何将自定义打印页与PdfiumViewer的PDF合并为同一份打印任务

实现方案

核心逻辑是自行创建统一的PrintDocument对象管理整个打印任务,第一页绘制二维码相关内容,第二页直接渲染PDF文件的内容,两个页面共用同一份打印配置,就能实现单任务连续打印。

具体实现步骤

  1. 先在类中定义两个成员变量,用来存储打印过程中需要复用的对象:
// 存储加载好的PDF文档对象
private PdfDocument _pdfToPrint;
// 打印页码计数器,0代表第一页(二维码页),1代表第二页(PDF页)
private int _currentPrintPageIndex = 0;
  1. 修改打印触发的方法,统一配置打印参数,绑定打印事件:
private void button1_Click(object sender, EventArgs e)
{
    string pdfPath = @textBox1.Text;
    PrintCombinedDocument("M2020", "A4", pdfPath, 1);
}

public bool PrintCombinedDocument(string printer, string paperName, string pdfFilename, int copies)
{
    try
    {
        // 预先加载要打印的PDF文档
        _pdfToPrint = PdfDocument.Load(pdfFilename);
        _currentPrintPageIndex = 0;

        // 配置打印机参数
        var printerSettings = new PrinterSettings
        {
            PrinterName = printer,
            Copies = (short)copies,
        };

        // 配置页面参数
        var pageSettings = new PageSettings(printerSettings)
        {
            Margins = new Margins(0, 0, 0, 0),
        };
        foreach (PaperSize paperSize in printerSettings.PaperSizes)
        {
            if (paperSize.PaperName == paperName)
            {
                pageSettings.PaperSize = paperSize;
                break;
            }
        }

        // 自行创建打印文档对象,统一管理两页打印
        using (var printDocument = new PrintDocument())
        {
            printDocument.PrinterSettings = printerSettings;
            printDocument.DefaultPageSettings = pageSettings;
            printDocument.PrintController = new StandardPrintController();
            // 绑定打印页处理事件
            printDocument.PrintPage += CombinedPrintPageHandler;
            // 执行打印
            printDocument.Print();
        }

        // 释放PDF资源
        _pdfToPrint.Dispose();
        return true;
    }
    catch
    {
        _pdfToPrint?.Dispose();
        return false;
    }
}
  1. 实现统一的打印页处理方法,根据当前页码判断绘制内容:
private void CombinedPrintPageHandler(object sender, PrintPageEventArgs e)
{
    if (_currentPrintPageIndex == 0)
    {
        // 第一页:绘制原来的二维码页内容,直接复用你原有的打印逻辑即可
        string s2 = "Modified by: ";
        string s6 = "Author: " + author;
        string s4 = "Created: " + drawdate;
        QRCodeGenerator qrGenerator1 = new QRCodeGenerator();
        QRCodeData qrCodeDataPrint = qrGenerator1.CreateQrCode(qrcodedata, QRCodeGenerator.ECCLevel.Q, false, false);
        Bitmap qrCodeImagePrint = (new QRCode(qrCodeDataPrint)).GetGraphic(20);
        Bitmap bmimg = new Bitmap(this.pictureBox2.Width, this.pictureBox2.Height);
        this.pictureBox2.DrawToBitmap(bmimg, new Rectangle(0, 0, this.pictureBox2.Width, this.pictureBox2.Height));
        System.Drawing.Font f1 = new System.Drawing.Font("Arial", 5f, FontStyle.Bold, GraphicsUnit.Millimeter);
        System.Drawing.Font f2 = new System.Drawing.Font("Arial", 2f, GraphicsUnit.Millimeter);
        System.Drawing.Font f3 = new System.Drawing.Font("Arial", 3f, GraphicsUnit.Millimeter);
        System.Drawing.Font barc = new System.Drawing.Font("Code39Azalea", 36f, GraphicsUnit.Point);
        e.Graphics.PageUnit = GraphicsUnit.Millimeter;
        Pen blackPen = new Pen(Color.Black, 1f);
        Rectangle rect = new Rectangle(165, 35, 30, 30);
        Rectangle qrcodetest = new Rectangle(170, 40, 25, 25);
        Rectangle btmimg = new Rectangle(60, 140, 120, 120);
        Rectangle combox = new Rectangle(20, 145, 160, 40);
        e.Graphics.DrawImage(qrCodeImagePrint, qrcodetest);
        e.Graphics.DrawRectangle(blackPen, qrcodetest);
        e.Graphics.DrawString(this.procreq, f1, Brushes.Black, new Point(50, 5));
        e.Graphics.DrawString(s1, f1, Brushes.Black, new Point(150, 70));
        e.Graphics.DrawString(s1z, f2, Brushes.Black, new Point(150, 75));
        e.Graphics.DrawString(qrissuedby, f2, Brushes.Black, new Point(20, 264));
        e.Graphics.DrawString(s6, f2, Brushes.Black, new Point(20, 267));
        e.Graphics.DrawString(s4, f2, Brushes.Black, new Point(20, 270));
        e.Graphics.DrawString(s2, f2, Brushes.Black, new Point(20, 273));
        e.Graphics.DrawString(s3, f2, Brushes.Black, new Point(20, 276));
        e.Graphics.DrawString(s5, f2, Brushes.Black, new Point(20, 279));
        e.Graphics.DrawString(this.notebox.Text, f3, Brushes.Black, combox);
        e.Graphics.DrawImage(bitmap1, btmimg);
        bmimg.Dispose();
        bitmap1.Dispose();

        // 标记还有下一页要打印
        e.HasMorePages = true;
        _currentPrintPageIndex++;
    }
    else if (_currentPrintPageIndex == 1)
    {
        // 第二页:渲染PDF的第一页内容
        e.Graphics.PageUnit = GraphicsUnit.Pixel;
        // 调用PdfiumViewer的Render方法把PDF页绘制到打印画布上
        using (var pdfPage = _pdfToPrint.Pages[0])
        {
            pdfPage.Render(
                e.Graphics,
                e.Graphics.VisibleClipBounds,
                new RectangleF(0, 0, pdfPage.Width, pdfPage.Height),
                GraphicsUnit.Pixel,
                true);
        }
        // 没有后续页面了
        e.HasMorePages = false;
        _currentPrintPageIndex = 0;
    }
}

注意事项

  • 如果你的PDF有多页需要打印,可以在第二页的逻辑里再加页码判断,依次渲染所有PDF页即可
  • 代码里用到的author、drawdate、qrcodedata等变量都是你原有代码里的全局/成员变量,不需要修改直接复用即可
  • 打印完成后记得释放PDF对象资源,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 22:15:07