提升你的C#技能:掌握PrintDocument实现打印操作的秘诀

前言:

我们用C#在开发应用的时候,经常需要打印操作,比如你需要打印某些记录,或者是某些图像都需要用到打印的操作,比如我需要打印报警记录,按照指定的格式打印出来,我需要PrintDocument类,将我需要的数据在PrintDocument上面规定好,再打印出来。PrintDocument 类提供了一种打印文档的方法,您可以使用它来打印文本、图像和其他内容。

PrintDocument类

PrintDocument 类是 C# 中用于打印文档的一个重要类。它提供了一种将文本、图像和其他内容打印到打印机的方法。通过 PrintDocument 类,可以控制打印页面的布局、字体、页眉和页脚等属性。它还提供了事件来处理打印过程中的各种情况,如开始打印、打印页面和完成打印等。PrintDocument 类是 System.Drawing.Printing 命名空间中的一部分,使用时需要引入该命名空间。

PrintDocument 类,通常需要以下步骤

1.创建一个 PrintDocument 对象。
2.设置打印文档的属性,如纸张大小、页边距、打印机设置等。
3.实现 PrintPage 事件处理程序,在该处理程序中指定要打印的内容和布局。
4.使用 Print 方法开始打印过程。

PrintDocument 属性

属性名
CanRaiseEvents 获取一个指示组件是否可以引发事件的值。(继承自 Component)
Container 获取包含 IContainer 的 Component。(继承自 Component)
DefaultPageSettings 获取或设置用作要打印的所有页的默认设置的页设置。
DesignMode 获取一个值,用以指示 Component 当前是否处于设计模式。(继承自 Component)
DocumentName 获取或设置打印文档时要显示的文档名称(例如,在打印状态对话框或打印机队列中)。
Events 获取附加到此 Component 的事件处理程序的列表。(继承自 Component)
OriginAtMargins 获取或设置一个值,该值指示与页关联的图形对象的位置是位于用户指定边距内,还是位于该页可打印区域的左上角。
PrintController 获取或设置指导打印进程的打印控制器。
Site 获取或设置 Component 的 ISite。(继承自 Component)
PrinterSettings 获取或设置对文档进行打印的打印机。

PrintDocument 方法

方法名
CreateObjRef(Type) 创建一个对象,该对象包含生成用于与远程对象进行通信的代理所需的全部相关信息。(继承自 [MarshalByRefObject)
Dispose() 释放由 Component 使用的所有资源。(继承自 Component)
Dispose(Boolean) 释放由 Component 占用的非托管资源,还可以另外再释放托管资源。(继承自 Component)
Equals(Object) 确定指定对象是否等于当前对象。(继承自 Object)
GetHashCode() 作为默认哈希函数。(继承自 Object)
GetLifetimeService() 检索控制此实例的生存期策略的当前生存期服务对象。(继承自 MarshalByRefObject)
GetService(Type) 返回一个对象,该对象表示由 Component 或它的 Container 提供的服务。(继承自 Component)
GetType() 获取当前实例的 Type。(继承自 Object)
InitializeLifetimeService() 获取生存期服务对象来控制此实例的生存期策略。(继承自 MarshalByRefObject)
MemberwiseClone() 创建当前 Object 的浅表副本。(继承自 Object)
MemberwiseClone(Boolean) 创建当前 MarshalByRefObject 对象的浅表副本。(继承自 MarshalByRefObject)
OnBeginPrint(PrintEventArgs) 引发 BeginPrint 事件。 该事件在调用 Print() 方法之后并在打印文档的第一页之前被调用。
OnEndPrint(PrintEventArgs) 引发 EndPrint 事件。 该事件在文档的最后一页打印完后被调用。
OnPrintPage(PrintPageEventArgs) 引发 PrintPage 事件。 该事件在某页打印之前被调用。
OnQueryPageSettings(QueryPageSettingsEventArgs) 引发 QueryPageSettings 事件。 该事件正好在每个 PrintPage 事件之前被调用。
Print() 开始文档的打印进程。
ToString() 以字符串形式提供有关打印文档的信息。

PrintDocument 事件

事件名
BeginPrint 在调用 Print() 方法之后、打印文档首页之前发生。
Disposed 在通过调用 Dispose() 方法释放组件时发生。(继承自 Component)
EndPrint 打印完文档的最后一页时发生。
PrintPage 当需要为当前页打印的输出时发生。
QueryPageSettings 在 PrintPage 事件的紧面前发生。
以下是 PrintDocument 类的常用属性:

PrinterSettings:获取或设置与打印机相关的设置,如选择打印机、纸张大小、打印份数等。 DefaultPageSettings:获取或设置与页面相关的设置,如页面大小、边距等。 DocumentName:获取或设置打印文档的名称。

以下是 PrintDocument 类的常用方法:

Print:开始打印文档。 PrintPage:打印每一页时触发的事件,可以在此事件处理程序中定义要打印的内容。 Dispose:释放 PrintDocument 对象使用的资源。

以下是 PrintDocument 类的常用事件:

PrintPage:在每一页打印时触发,可以在此事件处理程序中定义要打印的内容。

PrintDocument打印图像

我们先创建一个按钮,点击之后选择我们需要的图像,获取路径,将路径的图像打印。

arduino 复制代码
using System.Drawing;
using System.Drawing.Printing;//这是我们的引入,VS2019版本以上复制代码自动引入,vs2019以下手动引入
ini 复制代码
   private void button1_Click(object sender, EventArgs e)//按钮逻辑
        {
​
            // 创建一个OpenFileDialog对象
            OpenFileDialog openFileDialog = new OpenFileDialog();
​
            // 设置文件对话框的标题和筛选条件
            openFileDialog.Title = "选择文件";
            openFileDialog.Filter = "所有文件 (*.*)|*.*";
​
            // 打开文件对话框并获取用户选择的文件路径
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                name = openFileDialog.FileName;
            }
            Print(name);
        }
ini 复制代码
   public void Print(string imagePath)//打印操作逻辑
        {
            // 创建一个PrintDocument对象
            PrintDocument printDocument = new PrintDocument();
​
            // 设置PrintPage事件处理程序
            printDocument.PrintPage += (sender, e) =>
            {
                // 加载要打印的图像
                Image image = Image.FromFile(imagePath);
​
                // 计算图像在打印页面上的位置和大小
                RectangleF imageBounds = e.MarginBounds;
                float imageAspectRatio = image.Width / (float)image.Height;
                if (imageAspectRatio > 1)
                {
                    imageBounds.Width = e.MarginBounds.Width;
                    imageBounds.Height = e.MarginBounds.Width / imageAspectRatio;
                }
                else
                {
                    imageBounds.Height = e.MarginBounds.Height;
                    imageBounds.Width = e.MarginBounds.Height * imageAspectRatio;
                }
​
                // 绘制图像在打印页面上
                e.Graphics.DrawImage(image, imageBounds);
​
                // 通知打印系统还有更多页面需要打印
                e.HasMorePages = false;
​
                // 释放图像资源
                image.Dispose();
            };
​
            // 调用打印对话框并打印图像
            PrintDialog printDialog = new PrintDialog();
            printDialog.Document = printDocument;
            if (printDialog.ShowDialog() == DialogResult.OK)
            {
                printDocument.Print();
            }
        }
​

上面的操作只是简单的操作,我们会发现我看不到打印的效果,所以我们应该需要引入打印预览所以我们升级一下打印的操作

下面就是整体的代码演示

代码演示

建一个窗体,拖一个按钮,复制下面的代码就可以复现操作啦!

ini 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
​
namespace IC00
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
​
        private void Form1_Load(object sender, EventArgs e)
        {
​
        }
        string name;
        public void Print(string imagePath)
        {
            // 创建一个PrintDocument对象
            PrintDocument printDocument = new PrintDocument();
​
            // 设置PrintPage事件处理程序
            printDocument.PrintPage += (sender, e) =>
            {
                // 加载要打印的图像
                Image image = Image.FromFile(imagePath);//可以直接把图像获取在按钮里面做,我们Print操作形参设为图像Image也是可以的
​
                // 计算图像在打印页面上的位置和大小
                RectangleF imageBounds = e.MarginBounds;
                float imageAspectRatio = image.Width / (float)image.Height;
                if (imageAspectRatio > 1)
                {
                    imageBounds.Width = e.MarginBounds.Width;
                    imageBounds.Height = e.MarginBounds.Width / imageAspectRatio;
                }
                else
                {
                    imageBounds.Height = e.MarginBounds.Height;
                    imageBounds.Width = e.MarginBounds.Height * imageAspectRatio;
                }
                /*
                 我们使用e.MarginBounds获取打印页面的边距,并将其赋值给imageBounds变量。然后,我们计算图像的宽高比,通过将图像的宽度除以高度来获得。
                 如果图像的宽高比大于1,表示图像比较宽,我们将imageBounds的宽度设置为边距的宽度,然后根据宽高比计算出相应的高度。如果图像的宽高比小于等于1,
                 表示图像比较高,我们将imageBounds的高度设置为边距的高度,然后根据宽高比计算出相应的宽度。
                 */
                // 绘制图像在打印页面上
                e.Graphics.DrawImage(image, imageBounds);
​
                // 通知打印系统还有更多页面需要打印
                e.HasMorePages = false;
​
                // 释放图像资源
                image.Dispose();
            };
​
            // 创建一个PrintPreviewDialog对象
            PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog();
​
            // 设置打印预览对话框的PrintDocument属性
            printPreviewDialog.Document = printDocument;
​
            // 显示打印预览对话框
            if (printPreviewDialog.ShowDialog() == DialogResult.OK)
            {
                // 调用打印对话框并打印图像
                PrintDialog printDialog = new PrintDialog();
                printDialog.Document = printDocument;
                if (printDialog.ShowDialog() == DialogResult.OK)
                {
                    printDocument.Print();
                }
            }
        }
​
        private void button1_Click(object sender, EventArgs e)
        {
​
            // 创建一个OpenFileDialog对象
            OpenFileDialog openFileDialog = new OpenFileDialog();
​
            // 设置文件对话框的标题和筛选条件
            openFileDialog.Title = "选择文件";
            openFileDialog.Filter = "所有文件 (*.*)|*.*";
​
            // 打开文件对话框并获取用户选择的文件路径
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                name = openFileDialog.FileName;
            }
            Print(name);
        }
    }
}
​

PrintDocument打印文本或文本文件

打印纯文本

我们打印文本是可以打印纯文本,比如我们在一些操作里面想要打印一些消息队列啊,或者是一些报错的代码我们可以打印一些报错,得知报错信息,对我们的程序的提高高级感。

scss 复制代码
   public void PrintTxt(string text)//打印文本的方法
        {
            PrintDocument printDocument = new PrintDocument();
​
            // 设置PrintPage事件处理程序
            printDocument.PrintPage += (sender, e) =>
            {
                // 设置文本的字体和大小
                Font font = new Font("Arial", 12);
​
                // 设置文本的位置和大小
                RectangleF textBounds = e.MarginBounds;
​
                // 绘制文本在打印页面上
                e.Graphics.DrawString(text, font, Brushes.Black, textBounds);
​
                // 通知打印系统还有更多页面需要打印
                e.HasMorePages = false;
            };
​
            // 创建一个PrintPreviewDialog对象
            PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog();
​
            // 设置打印预览对话框的PrintDocument属性
            printPreviewDialog.Document = printDocument;
​
            // 显示打印预览对话框
            printPreviewDialog.ShowDialog();
        }
        
        private void button2_Click(object sender, EventArgs e)//按钮操作
        {
            PrintTxt("测试,测试,测试,IC00IC00IC00IC00IC00");
        }

打印文本文件

打印文本文件可以打印我们软件的日志,或者我们需要的一些参数都可以使用这个PrintDocument类进行打印,不需要再去写一个程序去进行打印操作。

ini 复制代码
     public void PrintTxtFile(string filePath)
        {
            // 创建一个PrintDocument对象
            PrintDocument printDocument = new PrintDocument();
​
            // 设置PrintPage事件处理程序
            printDocument.PrintPage += (sender, e) =>
            {
                // 设置文本的字体和大小
                Font font = new Font("Arial", 12);
​
                // 设置文本的位置和大小
                RectangleF textBounds = e.MarginBounds;
​
                // 读取文本文件的内容
                string text = File.ReadAllText(filePath);//这个是读取全部在txt文件里面数据,或者使用筛选逐条筛选
​
                // 绘制文本在打印页面上
                e.Graphics.DrawString(text, font, Brushes.Black, textBounds);
​
                // 通知打印系统还有更多页面需要打印
                e.HasMorePages = false;
            };
​
            // 创建一个PrintPreviewDialog对象
            PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog();
​
            // 设置打印预览对话框的PrintDocument属性
            printPreviewDialog.Document = printDocument;
​
            // 显示打印预览对话框
            printPreviewDialog.ShowDialog();
        }
        string filename;
       
ini 复制代码
 private void button3_Click(object sender, EventArgs e)
        {
            // 创建一个OpenFileDialog对象
            OpenFileDialog openFileDialog = new OpenFileDialog();
​
            // 设置文件对话框的标题和筛选条件
            openFileDialog.Title = "选择文件";
            openFileDialog.Filter = "所有文件 (*.*)|*.*";
​
            // 打开文件对话框并获取用户选择的文件路径
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                filename = openFileDialog.FileName;
            }
            PrintTxtFile(filename);
        }

扩展

我们可以打印word或者PDF是使用其他的方式,我这里就不简单介绍,后期文章可能会详细介绍,可以简单代码示例,后期会出详细教程

csharp 复制代码
using System;
using Microsoft.Office.Interop.Word;
​
public class PrintPreviewWordDocument
{
    public void PrintPreview(string filePath)
    {
        // 创建一个 Word 应用程序对象
        Application wordApp = new Application();
​
        // 打开 Word 文档
        Document wordDoc = wordApp.Documents.Open(filePath);
​
        // 显示打印预览
        wordApp.Visible = true;
​
        // 打印文档
        wordDoc.PrintOut();
​
        // 关闭 Word 文档
        wordDoc.Close();
​
        // 退出 Word 应用程序
        wordApp.Quit();
    }
}
​
ini 复制代码
PrintPreviewWordDocument printPreviewWordDocument = new PrintPreviewWordDocument();
printPreviewWordDocument.PrintPreview("C:\example.docx");//调用

注意在项目中引用 Microsoft.Office.Interop.Word 库,并确保您的计算机上安装了 Microsoft Office。

总结

这篇文章比较简单,只是简单的学习一下PrintDocument,对于初学PrintDocument来说是肯定够了的,对于方法属性事件的运用都有简单操作理解和代码分析,对它有更多的认识,在有需求的时候最起码有路子,虽然很简单,但是也是可以学到东西的,我们学习了新的知识,对我们的知识储备及技术又有新的一点点的进步,C#的技术就是先简单再难嘛,积少成多之后才会成长才会进步,我们要不断的学习不断的探索,才能有学习的动力,才会有学习的欲望,创作不易,点赞评论收藏关注,嘿嘿,不喜勿喷!!!!

相关推荐
NiNg_1_2341 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
Chrikk2 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*2 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue2 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man2 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang
customer084 小时前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源
Yaml45 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
小码编匠6 小时前
一款 C# 编写的神经网络计算图框架
后端·神经网络·c#