在当今互联网时代,大家都提倡无纸化绿色办公,如扫码,在线,小程序等,既提高了效率,又节约纸张,绿色环保,但在某些特定的场景与人群(如超市收银),打印票据或收据是必不可少的。今天我们以一些简单的小例子,简述基于.NET的Windows窗体编程中打印的常见用法,仅供学习分享使用,如有不足之处,还请指正。
概述
在WinForms开发框架中,主要使用 PrintDocument 组件进行打印,而PrintPreviewDialog和PrintDialog,PageSetupDialog组件为用户提供熟悉的图形界面。主要内容如下:
- PrintDialog,是一个预配置的对话框,通过ShowDialog方法显示对话框,此控件主要用于选择打印机、选择要打印的页面,并确定基于 Windows 的应用程序中的其他打印相关设置。通过PrintDialog可以设置打印的范围,如全部打印、打印所选页面范围或打印所选内容。
- PrintDocument,用于设置描述要打印的属性以及打印的内容,然后在基于 Windows 的应用程序中打印文档,通常与PrintDialog结合使用。
- PrintPreviewControl,用于预览文档打印时的样子,它没有按钮或其他用户界面元素,因此通常仅当希望编写自己的打印预览用户界面时,才使用此控件。
- PrintPreviewDialog,此控件是一个预配置的对话框,用于预览文档在打印时的内容,它包含用于打印、放大、显示一页或多页以及关闭对话框的按钮。
- PageSetupDialog,是一个预配置的对话框,用于设置在基于 Windows 的应用程序中打印的页面详细信息,通过PageSetupDialog可以设置边框和边距调整、页眉和页脚以及纵向和横向方向。
PrintDialog
用户可以通过PrintDialog弹出的对话框,选择打印机,以及要打印的页面。
PrintDialog关键属性:
- AllowCurrentPage,是否显示当前Page选项按钮,允许选择当前Page进行打印,默认为false。
- AllowPrintToFile,是否显示“打印到文件”复选框,默认为true。
- AllowSomePages,Pages选择是否可用,默认false,当为true时,可以选择打印的页码范围。
- AllowSelection,是否允许“选定范围”,默认false,当为true时,可以勾选“选定范围”复选框。
- Document,获取或设置能够从中获取PrinterSettings的文档。
- PrinterSettings,获取或设置打印机选定的打印机设置,如:设置属性Copies,可以设置打印份数,默认为1。
- PrintToFile,获取或设置“打印到文件”复选框是否勾选。
- ShowNetwork,是否显示“Network”按钮。
- UseEXDialog,是否显示WindowsXP风格的对话框,默认为false。
PrintDialog关键方法:
说明:经过验证,AllowCurrentPage,ShowNetWork两个属性在新版的操作系统中不生效。
PrintDocument
从 Windows 窗体应用程序打印时,定义一种可重用的可发送到打印机上的对象。
PrintDocument关键属性:
- DefaultPageSettings,定义默认的Page设置,当All Pages被打印时默认采用此配置。
- DocumentName,定义文档名称,当打印时在状态对话框或者打印队列中,会显示此名称。
- PrinterSettings,获取或设置选择的打印机,如:设置属性Copies,可以设置打印份数,默认为1。
PrintDocument关键事件:
- PrintPage,是PrintDocument组件最重要的事件,当调用Print方法开始打印时触发此事件,可以在此事件中编写打印逻辑。PrintPage事件包含PrintPageEventArgs参数,可以通过此参数获取Grapics对象,并通过Grapics对象绘制需要输出的内容。
- BeginPrint,当开始打印文档,且第一个Page开始打印之前触发此事件。
- EndPrint,当最后一个Page打印完成触发此事件。
PrintDocument关键方法:
PrintPreviewControl
PrintPreviewControl表示 Windows 窗体应用程序打印预览的原始预览部分,没有任何对话框或按钮。
PrintPreviewControl控件的关键属性:
- AutoZoom,当改变控件大小,或者显示页数时,是否自动使用Zoom属性,默认为true。
- Rows,Columns,控件预览时,每屏显示的行,列数量。
PrintPreviewControl的关键方法:
- InvalidatePreview,通过此方法刷新预览的文档。
PrintPreviewDialog
PrintPreviewDialog打印预览对话框,是UI框架内置的对话框,用于展示文档在打印时的外观。它包含用于打印、放大、显示一页或多页以及关闭对话框的按钮。
PrintPreviewDialog控件的关键属性:
- Document,用于设置需要预览的文档对象,为PrintDocument类型的实例。
- UseAntiAlias, 是否使用抗锯齿显示文档,抗锯齿可以使文本看起来更流畅,但它也可以使显示速度变慢。
PrintPreviewDialog关键方法:
- ShowDialog,通过此方法显示打印预览对话框。
PageSetupDialog
PageSetupDialog组件是一个预配置的对话框,用于设置在基于 Windows 的应用程序中打印的页面详细信息。用户可以设置边框和边距调整、页眉和页脚以及纵向和横向方向。
PageSetupDialog控件的关键属性:
- Document,获取或设置能够从中获取PageSettings的文档。
- AllowMargins,是否显示“页边距”设置选择项,默认为true。
- AllowOrientation,是否显示“方向”选择项,如横向,纵向打印,默认为true。
- AllowPaper,是否显示“纸张”选择项,如A4,B5选择等,默认为true。
- AllowPrinter,Printer按钮是否可用,默认为true。
- EnableMetric,边距是否自动在百分之英寸和毫米之间转换。
- MinMargins,最小边距,单位为百分之一英寸。
- PrinterSettings,获取或设置打印机相关属性。
综合实例
完整的实现打印功能,需要结合PrintDialog,PrintDocument,PrintPreviewControl,PrintPreviewDialog,PageSetupDialog,共同完成,接下来我们通过打印功能实现一个“录取通知书”的打印。
1. 布局UI页面
设计简单的UI页面,步骤如下:
- 通过SplitContainer控件让Form分为左右两部分,左侧用于输入信息,右侧显示打印“录取通知书”。
- 拖动PrintDocument控件到Form表单中,并命名为printDocument。
- 拖动PrintPreviewControl控件到Form表单的右侧Panel中,并命名为printPreviewControl。
- 拖动其他文本框控件,主要用于输入相关需要打印的信息。
- 拖动四个按钮,分别用于打印,预览,刷新,PageSetup。
UI布局完成后,如下所示:
2. 初始化打印信息
在Form的Load事件中初始化PrintDocument的DetaultPageSettings,主要用于设置页大小,边距,等信息。如下所示:
private void FrmPrint_Load(object sender, EventArgs e){
int width_in = MM2Inch(width_p); int height_in = MM2Inch(height_p); PaperSize paperSize= new PaperSize("customer", width_in, height_in); PrinterSettings printerSettings = new PrinterSettings(); printerSettings.PrintRange = PrintRange.AllPages; printerSettings.DefaultPageSettings.PaperSize = paperSize; PageSettings pageSetting = new PageSettings(printerSettings); pageSetting.PaperSize = paperSize; int margin_lr_in = MM2Inch(margin_lr); int margin_tb_in = MM2Inch(margin_tb); pageSetting.Margins = new Margins(margin_lr_in, margin_lr_in, margin_tb_in, margin_tb_in); this.printDocument.DefaultPageSettings = pageSetting; this.printPreviewControl.AutoZoom = true; this.printPreviewControl.Zoom = 1;}
在上述代码中用到的MM2Inch方法,主要用于毫米和百分之一英寸的换算:打印机是以百分之一英寸为单位的,单据设置是以毫米为单位的,所以需要转换,转换公式如下所示:
private int MM2Inch(int mm){ return (int)(mm * 100.0f / 25.4f);}
3. 打印逻辑
在PrintDocument的PrintPage事件中编写打印输出逻辑,主要通过Graphics对象输出边框,文本,图像等内容。具体如下所示:
private void printDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e){ if (e.Graphics == null) { return; } string school = this.txtSchool.Text; string student = this.txtStudent.Text; string department = this.txtDepartment.Text; string beginDate = this.txtDate.Text; string major = this.txtMajor.Text; string tuition = this.txtTuition.Text; string seal = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, this.txtSeal.Text); Graphics g = e.Graphics; Font defaultFont = new Font("Arial", 14f, FontStyle.Regular); Font schoolFont = new Font("宋体", 18f, FontStyle.Bold); Font keyFont = new Font("宋体", 16f, FontStyle.Bold | FontStyle.Underline); Font titleFont = new Font("Arial", 20f, FontStyle.Bold); Font qianMingFont = new Font("Rage Italic", 20f, FontStyle.Bold | FontStyle.Underline); Brush defaultBrush = Brushes.Black; g.DrawRectangle(Pens.Red, new RectangleF(new PointF(3, 3), new SizeF(466, 505))); g.DrawString(school, schoolFont, defaultBrush, new Point(10, 20)); g.DrawString("录取通知书", titleFont, Brushes.Red, new Point(130, 70)); g.DrawString($"_{student}_", keyFont, defaultBrush, new Point(10, 120)); g.DrawString("同学:", defaultFont, defaultBrush, new Point(100, 120)); g.DrawString("我校决定录取你入", defaultFont, defaultBrush, new Point(10, 170)); g.DrawString($"_{department}_", keyFont, defaultBrush, new Point(190, 170)); g.DrawString("学院(系)", defaultFont, defaultBrush, new Point(300, 170)); g.DrawString($"_{major}_", keyFont, defaultBrush, new Point(10, 220)); g.DrawString("专业学习。学费", defaultFont, defaultBrush, new Point(220, 220)); g.DrawString($"_{tuition}_", keyFont, defaultBrush, new Point(10, 270)); g.DrawString("元整,请你准时于", defaultFont, defaultBrush, new Point(95, 270)); g.DrawString($"_{beginDate}_", keyFont, defaultBrush, new Point(260, 270)); g.DrawString("之前到校报到。", defaultFont, defaultBrush, new Point(10, 320)); g.DrawString(school, defaultFont, defaultBrush, new Point(220, 400)); g.DrawString("2026 年 06 月 06 日", defaultFont, defaultBrush, new Point(210, 440)); g.DrawImage(Image.FromFile(seal), new Point(220, 330)); g.DrawString("校长:", defaultFont, defaultBrush, new Point(20, 420)); g.DrawString("okcoder", qianMingFont, defaultBrush, new Point(80, 415));}
4. 页面刷新
右侧通过PrintPreviewControl实现显示打印通知书功能,通过此控件的InvalidatePreview方法实现控件的刷新,如下所示:
private void btnRefresh_Click(object sender, EventArgs e){ this.printPreviewControl.InvalidatePreview();}
实现效果如下所示:
5. 打印预览
通过PrintPreviewDialog控件实现打印预览,此控件会弹出打印预览对话框,显示打印的内容,如下所示:
private void btnPreview_Click(object sender, EventArgs e){ PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog(); printPreviewDialog.Document = this.printDocument; printPreviewDialog.Width = this.printPreviewControl.Width + 30; printPreviewDialog.Height = this.printPreviewControl.Height + 50; printPreviewDialog.AutoScaleMode = AutoScaleMode.None; printPreviewDialog.PrintPreviewControl.AutoZoom = false; printPreviewDialog.PrintPreviewControl.Zoom = 1; printPreviewDialog.ShowDialog();}
点击预览按钮,效果如下所示:
6. 打印
打印功能通过PrintDialog对话框,选择和设置打印的相关信息,然后再调用PrintDocument对象的Print方法开始打印过程,如下所示:
private void btnPrint_Click(object sender, EventArgs e){ PrintDialog printDialog = new PrintDialog(); printDialog.Document = this.printDocument; printDialog.AllowCurrentPage = true; printDialog.AllowPrintToFile = true; printDialog.AllowSomePages = true; printDialog.AllowSelection = true; printDialog.ShowHelp = true; printDialog.ShowNetwork = true; printDialog.UseEXDialog = false; printDialog.PrinterSettings = this.printDocument.DefaultPageSettings.PrinterSettings; if (printDialog.ShowDialog() == DialogResult.OK) { this.printDocument.Print(); }}
点击“打印”按钮,弹出打印对话框,如下所示:
7. PageSetup
打印页的设置通过PageSetupDialog弹出打印页设置对话框,如下所示:
private void btnPageSetup_Click(object sender, EventArgs e){ PageSetupDialog pageSetupDialog = new PageSetupDialog(); pageSetupDialog.AllowMargins = true; pageSetupDialog.AllowOrientation = true; pageSetupDialog.AllowPaper = true; pageSetupDialog.AllowPrinter = true; pageSetupDialog.EnableMetric = true; pageSetupDialog.Document = this.printDocument; pageSetupDialog.MinMargins = new Margins(3, 3, 3, 3); if(pageSetupDialog.ShowDialog()==DialogResult.OK) { if (pageSetupDialog.PageSettings != null) { this.printDocument.DefaultPageSettings = pageSetupDialog.PageSettings; } }}
点击PageSetup按钮,效果如下所示:
源码获取
关于本系列的完整代码,可以通过gitee上的库进行获取:
https://gitee.com/ahsiang/winforms
关于本系列的其他文章,可参考如下链接:
1. 基于.NET的Windows窗体编程之WinForms入门简介
2. 基于.NET的Windows窗体编程之WinForms控件简介
3. 基于.NET的Windows窗体编程之WinForms布局简介
5. 基于.NET的Windows窗体编程之WinForms数据表格
6. 基于.NET的Windows窗体编程之WinForms列表控件
以上就是《基于.NET的Windows窗体编程之WinForms打印》的全部内容,关于更多详细内容,可参考官方文档。希望能够一起学习,共同进步。
阅读原文:https://mp.weixin.qq.com/s/msblsvSzkNL9ZrFXoGVa_w
该文章在 2026/5/30 17:03:24 编辑过