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

news2024/11/26 21:31:11

前言:

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

ceeb653ely1g1ws2e1kjjj20du0f7q8r.jpg

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打印图像

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

using System.Drawing;
using System.Drawing.Printing;//这是我们的引入,VS2019版本以上复制代码自动引入,vs2019以下手动引入

image-20231031093106900.png

image-20231031093233095.png

image-20231031093436491.png

image-20231031093532155.png

我们创建一个个PrintDocument对象,设置PrintPage事件处理程序,加载我们需要打印的图像,计算好计算图像在打印页面上的位置和大小绘制图像,在打印页面上通知打印系统还有更多页面需要打印释放图像资源,具体代码如下所示

   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();
            }
        }
​

上面的操作只是简单的操作,直接调用打印的程序,直接调用,使得我们会发现我看不到打印的效果,所以我们应该需要引入打印预览所以我们升级一下打印的操作,我们需要可以看到打印内容的方式,这样可以避免我们打印的内部不出错,不会浪费纸张,下面我们需要升级一下打印操作

image-20231031094519562.png
上图是我们使用了打印预览的代码进行打印,可以清晰的看到我们需要打印的内容。

打印预览代码演示

我们使用e.MarginBounds获取打印页面的边距,并将其赋值给imageBounds变量。然后,我们计算图像的宽高比,通过将图像的宽度除以高度来获得。如果图像的宽高比大于1,表示图像比较宽,我们将imageBounds的宽度设置为边距的宽度,然后根据宽高比计算出相应的高度。如果图像的宽高比小于等于1,表示图像比较高,我们将imageBounds的高度设置为边距的高度,然后根据宽高比计算出相应的宽度。下面就是代码演示

        string name;
        public void Print(string imagePath)
        {
            // 创建一个PrintDocument对象
            PrintDocument printDocument = new PrintDocument();
​
            // 设置PrintPage事件处理程序
            printDocument.PrintPage += (sender, e) =>
            {
                // 加载要打印的图像
                Image image = Image.FromFile(imagePath);//可以直接把图像获取在按钮里面做,我们Print操作形参设为图像Image也是可以的
​  /*
                 我们使用e.MarginBounds获取打印页面的边距,并将其赋值给imageBounds变量。然后,我们计算图像的宽高比,通过将图像的宽度除以高度来获得。
                 如果图像的宽高比大于1,表示图像比较宽,我们将imageBounds的宽度设置为边距的宽度,然后根据宽高比计算出相应的高度。如果图像的宽高比小于等于1,
                 表示图像比较高,我们将imageBounds的高度设置为边距的高度,然后根据宽高比计算出相应的宽度。
                 */
                // 计算图像在打印页面上的位置和大小
                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();
            };
​
            // 创建一个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打印文本或文本文件

打印纯文本

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

image-20231031100231982.png

代码演示

下面是我们直接打印文本信息代码,我们通过使用PrintDocument对文本的字体,文本的大小,文本的位置,绘制在界面上面,并打印预览。

   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类进行打印,不需要再去写一个程序去进行打印操作。

image-20231031102117475.png

代码演示

下面是我们打印我们需要的Txt文本文件的方法,我们在使用读取需要打印文本文件的位置,获取路径,将我们需要打印的文本文件读出来,再调用打印的方法进行打印,我们可以将需要的打印文本文件按行打印出来,只要我们保存文本的时候有每行的结束标志,筛选一下赋值给string[] 我们就可以把每一行的文本打印。下面的代码时直接打印全部的文字。

     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;
 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是使用其他的方式,我这里就不简单介绍,后期文章可能会详细介绍,可以简单代码示例,后期会出详细教程

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();
    }
}
​
PrintPreviewWordDocument printPreviewWordDocument = new PrintPreviewWordDocument();
printPreviewWordDocument.PrintPreview("C:\example.docx");//调用

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

总结

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

520520

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1175665.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

项目管理之如何识别并应对项目风险

项目风险管理是项目管理中不可忽视的环节,如何识别并应对项目的风险对于项目的成功实施至关重要。本文将介绍风险管理的流程、风险分解结构、定性及定量风险评估方法,以及消极和积极的风险应对策略,旨在帮助读者更好地理解和应对项目风险。 …

(1)(1.12) LeddarTech LeddarVu8

文章目录 前言 1 连接到自动驾驶仪 2 参数说明 前言 LeddarTech LeddarVu8 是一款长距离(185m)激光雷达,可在 16 度至 99 度视场范围内提供 8 个单独的距离,具体取决于所使用的型号。ArduPilot 始终使用所提供的 8 个距离中最…

VSCode设置中文语言界面(VScode设置其他语言界面)

一、下载中文插件 二、修改配置 1、使用快捷键 CtrlShiftP 显示出搜索框 2、然后输入 configure display language 3、点击 (中文简体) 需要修改的语言配置 三、重启 四、可能出现的问题 1、如果configure display language已经是中文配置,界面仍是英文 解决&a…

优化C++资源利用:探索高效内存管理技巧

W...Y的主页 😊 代码仓库分享💕 🍔前言: 我们之前在C语言中学习过动态内存开辟,使用malloc、calloc与realloc进行开辟,使用free进行堆上内存的释放。进入C后对于动态内存开辟我们又有了新的内容new与dele…

【C++】一篇文章搞懂auto关键字及其相关用法!

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …

C语言基础篇1:数据类型、常量、变量

1 C语言基础 1.1 关键字 在C语言中,关键字是指被赋予特定意义的一些单词,不能把这些单词作为标识符来使用.C语言一共有32个关键字,如下图。在后面的学习中会逐渐接触到这些关键字的具体使用用法。 1.2 标识符 标识符可以简单的理解为一个名字…

第四届辽宁省大学生程序设计竞赛(正式赛)(12/13)

AC情况 赛中通过赛后通过暂未通过A√B√C√D○E○F√G√H√I○J√K—L√M√ 整体体验 easy:ABFHL mid:MJGC hard:IDKE 心得 感觉出了一堆典题,少数题还有些意思,E题确实神仙 题解 A. 欢迎来到辽宁省赛&#x…

bff层解决了什么痛点

bff层 -- 服务于前端的后端 什么是bff? Backend For Frontend(服务于前端的后端),也就是服务器设计API的时候会考虑前端的使用,并在服务端直接进行业务逻辑的处理,又称为用户体验适配器。BFF只是一种逻辑…

基于爬行动物算法的无人机航迹规划-附代码

基于爬行动物算法的无人机航迹规划 文章目录 基于爬行动物算法的无人机航迹规划1.爬行动物搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要:本文主要介绍利用爬行动物算法来优化无人机航迹规划。 …

Python|OpenCV-图像的添加和混合操作(8)

前言 本文是该专栏的第8篇,后面将持续分享OpenCV计算机视觉的干货知识,记得关注。 在使用OpenCV库对图像操作的时候,有时需要对图像进行运算操作,类似于加法,减法,位操作等处理。而本文,笔者将针对OpenCV对图像的添加,混合以及位操作进行详细的介绍说明和使用。 下面,…

03、SpringBoot + 微信支付 ---- 创建订单、保存二维码url、显示订单列表

目录 Native 下单1、创建课程订单保存到数据库1-1:需求:1-2:代码:1-3:测试结果: 2、保存支付二维码的url2-1:需求:2-2:代码:2-3:测试:…

python 之 sorted 函数

文章目录 sorted() 函数的语法返回值使用示例:示例 1:基本使用示例 2:指定降序排序示例 3:使用 key 参数进行自定义排序 注意事项: sorted() 是 Python 中的一个内置函数,用于对可迭代对象进行排序&#xf…

jquery之checkbox全选反选提交参数

实现效果 <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>Checkbox操作示例</title><script src"https://code.jquery.com/jquery-3.5.1.min.js"></script><script>$(document).ready(…

FPGA高端项目:图像缩放+GTP+UDP架构,高速接口以太网视频传输,提供2套工程源码加QT上位机源码和技术支持

目录 1、前言免责声明本项目特点 2、相关方案推荐我这里已有的 GT 高速接口解决方案我这里已有的以太网方案我这里已有的图像处理方案 3、设计思路框架设计框图视频源选择ADV7611 解码芯片配置及采集动态彩条跨时钟FIFO图像缩放模块详解设计框图代码框图2种插值算法的整合与选择…

【数据结构与算法】JavaScript实现哈希表

文章目录 一、哈希表简介1.1.认识哈希表1.2.哈希化的方式1.3.解决冲突的方法1.4.寻找空白单元格的方式线性探测二次探测再哈希化 1.5.不同探测方式性能的比较1.6.优秀的哈希函数快速计算均匀分布 二、初步封装哈希表2.1.哈希函数的简单实现2.2.创建哈希表2.3.put(key,value)2.4…

时间序列预测模型实战案例(七)(TPA-LSTM)结合TPA注意力机制的LSTM实现多元预测

论文地址->TPA-LSTM论文地址 项目地址-> TPA-LSTM时间序列预测实战案例 本文介绍 本文通过实战案例讲解TPA-LSTM实现多元时间序列预测&#xff0c;在本文中所提到的TPA和LSTM分别是注意力机制和深度学习模型,通过将其结合到一起实现时间序列的预测&#xff0c;本文利用…

Google发布移动终端对象检测模型——mediapipe,无GPU依然飞快

对象检测模型最出名的当选YOLO系列,其YOLO系列已经更新到V8系列,但是现有的YOLO模型面临限制,如量化支持不足和准确性延迟权衡不足。 YOLO-NAS模型在包括COCO、Objects365和Roboflow 100在内的知名数据集上进行了预训练,使其非常适合生产环境中的下游对象检测任务。YOLO-NA…

unity【动画】脚本_角色动画控制器 c#

首先创建一个代码文件夹Scripts 从人物角色Player的基类开始 创建IPlayer类 首先我们考虑到如果不挂载MonoBehaviour需要将角色设置成预制体实例化到场景上十分麻烦&#xff0c; 所以我们采用继承MonoBehaviour类的角色基类方法写代码 也就是说这个脚本直接绑定在角色物体…

Quartz之JDBC-JobStoreTX配置

一、前言 上篇 《Quartz介绍》中使用的是RAMJobStored存储调度信息&#xff0c;当进程终止调度信息会丢失&#xff0c;本篇我们介绍使用JDBCJobStore来存储调度信息&#xff08;jobs、Triggers和日历&#xff09;。 二、Quartz 表结构 可以从官网&#xff08;http://www.qua…

康耐视深度学习ViDi-ViDi四大工具介绍与主要用途

Cognex ViDi 工具是一系列机器视觉工具&#xff0c;通过深度学习解决各种难以解决的挑战。虽然这些工具共享一个引擎&#xff0c;但它们在图像中寻找的内容不同。更具体地说&#xff0c;在分析单个点、单个区域或完整图像时&#xff0c;每个工具都有不同的侧重点。 Locate&…