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

.NET中预创建Graphics对象传入PrintDocument实现高清打印问题咨询

原方案失效原因

你自行创建的Graphics对象绑定的是自定义上下文(通常为内存位图或设备无关上下文),和PrintPage事件参数中e.Graphics绑定的打印机硬件上下文完全独立。你对局部变量benis的重新赋值仅修改了引用指向,既不会改变事件参数内的Graphics属性(该属性本身为只读),也无法将预绘制的内容同步到打印机上下文。转位图打印会丢失矢量信息导致模糊,确实不可取。

可行实现方案

调整封装思路,将类库从「预生成Graphics对象」改为「接收Graphics对象执行绘制」,既可以完全隔离WinForm依赖,又能保证绘制内容直接输出到打印机上下文,无精度损失。
核心逻辑:类库只存储打印内容、样式配置,不提前执行绘制,上层调用方传入对应场景的Graphics(打印、预览都可适配)后,类库再执行绘制操作。
该方案优势:

  • 类库不需要依赖System.Windows.Forms,仅需引用System.Drawing相关包即可,符合依赖隔离要求
  • 所有绘制直接作用于打印机上下文,矢量文字、图形不会出现模糊问题,和直接在PrintPage中绘制的效果完全一致
  • 兼容打印预览场景,预览时传入预览控件的Graphics即可得到和实际打印完全一致的效果
  • 逻辑完全解耦,后续如果要扩展导出为图片、PDF等功能,只需要传入对应场景的Graphics即可,不需要修改绘制逻辑

代码实现示例

1. 类库改造

public class GebeDrucker
{
    // 保留所有配置参数存储,不提前绘制
    private C_BillPrint.Alignments _alignment;
    private string _headingText;
    private Font _headingFont;
    private Bitmap _logo;
    private Font _tableFont;
    private string _qrContent;
    // 其他需要用到的表格数据、计算参数等也一并存储

    // 原有的配置方法保持不变,仅做参数存储
    public void F_Alignment(C_BillPrint.Alignments alignment) => _alignment = alignment;
    public void F_DrawHeading(string text, Font font) 
    {
        _headingText = text;
        _headingFont = font;
    }
    public void F_DrawLogo(Bitmap logo) => _logo = logo;
    public void F_Drawtable(Font font) => _tableFont = font;
    public void F_QR(string content) => _qrContent = content;

    // 新增统一绘制入口,接收外部传入的Graphics对象
    public void DrawToTargetGraphics(Graphics g)
    {
        // 把你原本绘制到内部this.bill的所有逻辑迁移到这里,全部用传入的g执行绘制
        g.Clear(Color.White);
        SolidBrush drawBrush = new SolidBrush(Color.Black);
        
        // 示例:绘制标题
        if (!string.IsNullOrEmpty(_headingText))
        {
            float C_X = 5.0F;
            float C_Y = 5.0F;
            // 对齐计算逻辑保持不变
            g.DrawString(_headingText, _headingFont, drawBrush, C_X, C_Y);
        }
        // 剩余绘制logo、表格、二维码的逻辑同理替换即可
    }

    // 原有返回纸张宽高的方法保留,用于上层设置打印参数
    public int returnwidth() => 你的纸张宽度计算逻辑;
    public int returnheight() => 你的纸张高度计算逻辑;
}

2. 打印事件改造

public void printdoc1_PrintPage(object sender, PrintPageEventArgs e)
{
    // 直接调用类库绘制方法,传入打印机上下文的Graphics即可
    GebeDrucker.DrawToTargetGraphics(e.Graphics);
    // 单页打印设为false,多页打印按需处理分页逻辑
    e.HasMorePages = false;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 08:15:03