在C# Windows Form中实现发票打印及解决内容覆盖问题
WinForm打印发票内容重叠问题解决办法
嘿,作为编程新手遇到这种打印布局问题太正常啦,别担心!我来帮你梳理一下问题所在和解决办法~
你遇到的内容覆盖上一行的问题,核心原因是打印时没有正确控制绘制内容的Y坐标偏移——每次绘制新内容时,没有把绘制位置往下移动,导致新内容直接叠在了上一行的位置上。
结合你给出的代码片段,我猜你可能是在设置打印预览时,没有正确关联PrintDocument的PrintPage事件,或者在绘制文本时没有维护当前的Y位置变量。下面是具体的修正思路和示例代码:
关键解决步骤
- 用
PrintDocument作为打印逻辑的核心载体,所有内容绘制都在它的PrintPage事件中完成 - 维护一个
currentY变量,记录当前绘制内容的垂直位置,每次绘制后更新这个值(加上文本高度+行间距) - 使用
Graphics.MeasureString获取文本的实际高度,确保行间距适配不同字体大小
修正后的示例代码
// 先定义全局的PrintDocument实例,用于承载打印逻辑 private PrintDocument _printDocument = new PrintDocument(); private void ShowPrintPreview() { Form previewForm = new Form(); PrintPreviewControl previewControl = new PrintPreviewControl(); // 将PrintDocument关联到预览控件,预览内容由它生成 previewControl.Document = _printDocument; // 订阅PrintPage事件,在这里绘制发票的所有内容 _printDocument.PrintPage += OnPrintPage; // 配置预览窗体和控件 previewControl.Dock = DockStyle.Fill; previewForm.Controls.Add(previewControl); previewForm.Size = new Size(800, 600); previewForm.Text = "发票打印预览"; previewForm.ShowDialog(); } // 打印内容的核心处理事件 private void OnPrintPage(object sender, PrintPageEventArgs e) { // 初始化垂直起始位置,从页边距顶部往下50像素开始 float currentY = e.MarginBounds.Top + 50; float leftX = e.MarginBounds.Left; // 用页边距定位,避免内容超出纸张范围 float lineSpacing = 8; // 自定义行间距 // 1. 绘制发票标题 Font titleFont = new Font("微软雅黑", 16, FontStyle.Bold); string titleText = "XX科技有限公司 增值税普通发票"; e.Graphics.DrawString(titleText, titleFont, Brushes.Black, leftX, currentY); // 更新Y坐标:标题高度 + 行间距 currentY += e.Graphics.MeasureString(titleText, titleFont).Height + lineSpacing * 2; // 2. 绘制客户信息 Font infoFont = new Font("微软雅黑", 10); string customerText = "客户名称:张三 | 联系电话:138XXXX1234"; e.Graphics.DrawString(customerText, infoFont, Brushes.Black, leftX, currentY); currentY += e.Graphics.MeasureString(customerText, infoFont).Height + lineSpacing; // 3. 绘制商品列表(示例) string[] goodsList = { "商品1:编程入门教程 | 单价:59元 | 数量:1", "商品2:鼠标 | 单价:39元 | 数量:2" }; foreach (string goods in goodsList) { e.Graphics.DrawString(goods, infoFont, Brushes.Black, leftX, currentY); currentY += e.Graphics.MeasureString(goods, infoFont).Height + lineSpacing; } // 4. 绘制总金额 string totalText = $"总金额:{(59 + 39*2)}元"; Font totalFont = new Font("微软雅黑", 10, FontStyle.Bold); e.Graphics.DrawString(totalText, totalFont, Brushes.Red, leftX, currentY); // 释放字体资源,避免内存泄漏 titleFont.Dispose(); infoFont.Dispose(); totalFont.Dispose(); }
额外提示
- 如果你需要打印多页,可以在
PrintPage事件中设置e.HasMorePages = true,并维护页码等状态 - 测试时可以先用打印预览确认布局,没问题再实际打印
- 尽量使用系统自带字体,避免目标机器没有对应字体导致布局错乱
作为新手,刚开始接触WinForm打印确实容易忽略坐标控制的细节,多调试几次就能掌握啦~
内容的提问来源于stack exchange,提问作者Daron
相关产品推荐
相关产品推荐

