C# WinForm DataGridView按行指定不同打印机打印实现求助
C# WinForm 按行匹配打印机批量打印DataGridView内容实现方案
前置准备
- 提前确认DataGridView中存储打印目标的列字段值,和系统已安装打印机的官方名称完全对齐(和
PrinterSettings.InstalledPrinters枚举值匹配,注意保留名称中的空格、特殊字符),代码中读取目标列的逻辑需要替换为你实际界面的列名 - 排除DataGridView自带的未提交新增空行干扰,避免打印无效内容
核心实现流程
- 打印按钮触发点击事件后,先对所有有效数据行按打印目标值做分组,将指向同一台打印机的行归为同一个打印任务组,避免逐行提交任务造成打印队列错乱
- 为每个分组单独实例化
PrintDocument对象,给对象绑定对应分组的打印机名称,校验打印机状态有效性 - 给每个
PrintDocument绑定自定义的内容绘制事件,按排版规则把当前分组的所有行内容绘制到打印画布上 - 逐组触发静默打印,单组任务添加独立异常捕获,避免单台打印机故障导致全流程中断
参考代码示例
private void btnBatchPrint_Click(object sender, EventArgs e) { // 按打印目标对有效行分组 var printGroups = dataGridView1.Rows .Cast<DataGridViewRow>() .Where(row => !row.IsNewRow) // 过滤DataGridView默认的新增空行 .GroupBy(row => row.Cells["PrinterTarget"].Value?.ToString().Trim()) .Where(group => !string.IsNullOrEmpty(group.Key)); foreach (var group in printGroups) { try { var printDoc = new PrintDocument(); // 指定当前任务对应的打印机 printDoc.PrinterSettings.PrinterName = group.Key; // 校验打印机是否合法可用 if (!printDoc.PrinterSettings.IsValid) { MessageBox.Show($"目标打印机 {group.Key} 未找到,请检查设备连接状态"); continue; } // 绑定内容绘制逻辑 printDoc.PrintPage += (s, args) => { // 自定义绘制方法:按界面DataGridView的列布局,把group内的所有行内容逐行绘制到打印画布 RenderGridRowsToPrintCanvas(args.Graphics, group.ToList()); }; // 触发静默打印 printDoc.Print(); } catch (Exception ex) { MessageBox.Show($"发送到打印机 {group.Key} 失败:{ex.Message}"); } } } // 打印内容绘制方法(示例结构) private void RenderGridRowsToPrintCanvas(Graphics g, List<DataGridViewRow> rows) { float currentY = 50; // 打印起始Y坐标 // 固定绘制表格表头 foreach (DataGridViewColumn col in dataGridView1.Columns) { g.DrawString(col.HeaderText, this.Font, Brushes.Black, col.Left, currentY); } currentY += 30; // 逐行绘制单元格内容 foreach (var row in rows) { foreach (DataGridViewCell cell in row.Cells) { g.DrawString(cell.Value?.ToString(), this.Font, Brushes.Black, cell.ColumnIndex * 100, currentY); } currentY += 25; // 行高偏移 } }
注意事项
- 不要逐行创建
PrintDocument对象直接提交打印,会导致多打印机任务在打印队列中交叉错乱 - 打印机名称匹配时不要做字符串裁剪、大小写转换,Windows系统打印机名称是精确匹配的,带空格的名称(如
Printer 1)必须原样传入 - 若需要支持多页打印,需要在
PrintPage事件中维护已打印的行游标,当当前页排版满时设置e.HasMorePages = true继续后续内容打印,直到所有行打印完成
内容的提问来源于stack exchange,提问作者Cavid Hemidzade
相关产品推荐
相关产品推荐

