您现在的位置是:首页 >技术杂谈 >C# 使用自带的组件PrintPreviewDialog 和 PrintDocument实现打印预览(一)网站首页技术杂谈

C# 使用自带的组件PrintPreviewDialog 和 PrintDocument实现打印预览(一)

唠嗑一夏 2024-06-04 12:00:02
简介C# 使用自带的组件PrintPreviewDialog 和 PrintDocument实现打印预览(一)

前言

有这么个需求:DataTable中有一些数据是需要给显示或直接可以连接打印机进行打印的, 查阅了一下资料,发现官方就有组件PrintPreviewDialog和PrintDocument能实现这个功能。

相关内容了解

1 PrintPreviewDialog是一个打印预览的对话框,有打印,缩放、页面显示、选择页数、关闭等按钮。
长得就是这个样子。
在这里插入图片描述
2 PrintDocument类:是一个可以发送到打印机上的对象

3 PrintDocument.PrintPage 事件 当需要为当前页打印的输出时发生
4 PaperSize 类 指定纸张的大小
5 PageSettings.PaperSize 属性 获取或设置该页的纸张大小
6 PrinterSettings 类 指定打印时如何打印文档的信息,包括打印文档的打印机
7 PaperKind 枚举 指定标准纸张大小

8 Margins 类 指定打印页的边距尺寸

左上角的坐标点是(MarginBounds.X, MarginBounds.Y)

e.MarginBounds.Right = e.MarginBounds.Left + e.MarginBounds.Width
e.MarginBounds.Bottom = e.MarginBounds.Top + e.MarginBounds.Height

在这里插入图片描述
具体可以查看MSDN的介绍:
1、PrintDocument 类 https://learn.microsoft.com/zh-cn/dotnet/api/system.drawing.printing.printdocument?view=dotnet-plat-ext-7.0
2、Margins 类 https://learn.microsoft.com/zh-cn/dotnet/api/system.drawing.printing.margins?view=dotnet-plat-ext-7.0

打印预览功能

1 创建winform工程

先创建一个winform工程,在窗体上放置了一个Button,名称是btnPreView打印预览的入口按钮,
还有一个PrintDocument组件,名称是myDocument用于呈现要打印的内容。

在这里插入图片描述

2 创建要打印的测试数据

使用一个全局DataTable 名为saveTable存放测试数据。这里创建了100 行* 5列的数据,每列分别是 序号、名称、当前值、描述和默认值这五列。当然这只是我赋予的意义,为了好记而已。

        /// <summary>
        /// 构建临时数据表
        /// </summary>
        /// <returns></returns>
        private DataTable CreateTable()
        {
            DataTable dt = new DataTable();
            DataColumn col1 = new DataColumn("Num", typeof(string)); //序号
            DataColumn col2 = new DataColumn("Name", typeof(string)); //名称
            DataColumn col3 = new DataColumn("Val", typeof(string));  //当前值
            DataColumn col4 = new DataColumn("Des", typeof(string));  //描述
            DataColumn col5 = new DataColumn("Set", typeof(string)); //默认值

            dt.Columns.Add(col1);
            dt.Columns.Add(col2);
            dt.Columns.Add(col3);
            dt.Columns.Add(col4);
            dt.Columns.Add(col5);

            Random random = new Random();
            List<string> nameList = new List<string>
            {
                "A", "BB", "CCC", "D",
                "E", "F", "G","H","II",
                "JJ", "LL", "M"
            };

            List<string> tempList = new List<string>
            {
                "dsd", "sdfdgvre", "Hello", "Gilrs",
                "Today", "YYYY", "dfgre","GSD","fdgfer",
                "Wesd", "DLG", "fsdahfi;o"
            };

            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    DataRow dr = dt.NewRow();
                    //序号
                    dr[0] = "KK" + i.ToString("d2") + "." + j.ToString("d2");
                    //名称
                    dr[1] = nameList[j];

                    //当前值
                    if (j % 3 == 0)
                    {
                        dr[2] = random.NextDouble().ToString("f3");
                    }
                    else
                    {
                        dr[2] = i * j - random.Next(0, 30);
                    }
                    //描述
                    dr[3] = tempList[j];

                    //出厂值
                    dr[4] = random.NextDouble().ToString("f2");

                    //添加新行
                    dt.Rows.Add(dr);
                }
            }

            return dt;
        }

3 绘制打印页

这里的绘制分为三个部分,表头、内容和页脚。绘制方法都是大同小异,只是为了模块化,划分了不同区域。使用Draw绘制,重要的是找到要绘制点的X 、Y 坐标,通过MeasureString计算字体的高度, 其余的功能都还比较简单。
先看一下要打印的模板,类似下图。在这里插入图片描述

绘制标题(页眉) 序号 名称

        /// <summary>
        /// 绘制标题头
        /// </summary>
        /// <param name="e">绘图对象</param>
        /// <param name="tempTop">Y轴坐标</param>
        /// <param name="tempFormat">字符串格式</param>
        private void DrawTitle(System.Drawing.Printing.PrintPageEventArgs e,
            int tempTop, StringFormat tempFormat)
        {
            //绘制水平线
            e.Graphics.DrawLine(Pens.Black,
                new Point(e.MarginBounds.Left, tempTop),
                new Point(e.MarginBounds.Right, tempTop));

            Font printFont = new Font(fontName, fontNum);

            //计算字体的高度 K00ARk, 根据使用到的字进行组合成串
            int fontHeight = (int)(e.Graphics.MeasureString("K00ARk", printFont).Height);

            //画刷
            SolidBrush brush = new SolidBrush(Color.Black);

            //填充背景色
            e.Graphics.FillRectangle(Brushes.LightBlue,
                new RectangleF(e.MarginBounds.Left, tempTop, e.MarginBounds.Width, fontHeight));


            //列的序号
            int col = 0;

            //列 序号
            string drawString = TitleStr[col];
            //矩形框
            RectangleF rectangle = new RectangleF((int)cellLeft[col], tempTop,
                                       (int)cellWidth[col], fontHeight);

            e.Graphics.DrawString(drawString, printFont,
                                  brush, rectangle, tempFormat);
            col++;

            //列 名称
            drawString = TitleStr[col];
            //水平向右平移 并设置矩形框的宽度
            rectangle.X = cellLeft[col];
            rectangle.Width = cellWidth[col];
            e.Graphics.DrawString(drawString, printFont,
                brush, rectangle, tempFormat);
            col++;

            //列 设定值
            drawString = TitleStr[col];
            //水平向右平移 并设置矩形框的宽度
            rectangle.X = cellLeft[col];
            rectangle.Width = cellWidth[col];
            e.Graphics.DrawString(drawString, printFont,
                brush, rectangle, tempFormat);
            col++;

            //列 默认值
            drawString = TitleStr[col];
            //水平向右平移 并设置矩形框的宽度
            rectangle.X = cellLeft[col];
            rectangle.Width = cellWidth[col];
            e.Graphics.DrawString(drawString, printFont,
                brush, rectangle, tempFormat);
        }

绘制页脚

在底部添加公司信息和页码作为页脚。

        /// <summary>
        /// 绘制页脚
        /// </summary>
        /// <param name="e">绘图对象</param>
        /// <param name="pageNo">页面序号</param>
        private void DrawFooter(System.Drawing.Printing.PrintPageEventArgs e, int pageNo)
        {
            Font font = new Font("微软雅黑", 10);

            //绘制直线
            e.Graphics.DrawLine(new Pen(Color.Black, 1),
                new Point(e.MarginBounds.Left, e.MarginBounds.Bottom),
                new Point(e.MarginBounds.Right, e.MarginBounds.Bottom));

            //公司信息标注
            string tempStr = "Test for Windows(C) by 唠嗑一夏 Electric Corporation";

            e.Graphics.DrawString(tempStr,
              font, Brushes.Black,
              e.MarginBounds.Left,
              e.MarginBounds.Bottom+2);
            
            //页脚序号
            tempStr = pageNo.ToString();
            e.Graphics.DrawString(tempStr,
                font, Brushes.Black,
                e.MarginBounds.Right -  e.Graphics.MeasureString(tempStr, font).Width,
                e.MarginBounds.Bottom+2);
        }

绘制内容

一行一行的绘制DataTable中的数据内容。

        /// <summary>
        /// 绘制内容
        /// </summary>
        ///  <param name="e">绘图对象</param>
        ///  <param name="printIndex">数据行索引</param>
        /// <param name="tempTop">Y轴坐标</param>
        /// <param name="tempFormat">字符串格式</param>
        private void DrawContent(System.Drawing.Printing.PrintPageEventArgs e, 
                     int printIndex, int tempTop, StringFormat tempFormat)
        {
            Font printFont = new Font(fontName, fontNum);

            //计算字体的高度 K00ARk, 根据使用到的字进行组合成串
            int fontHeight = (int)(e.Graphics.MeasureString("K00ARk", printFont).Height);

            //画刷
            SolidBrush brush = new SolidBrush(Color.Black);

            //列的序号
            int col = 0;

            //列 序号
            string drawString = saveTable.Rows[printIndex][0].ToString() + saveTable.Rows[printIndex][1].ToString();
             //矩形框
            RectangleF rectangle = new RectangleF((int)cellLeft[col], tempTop,
                                       (int)cellWidth[col], fontHeight);

            e.Graphics.DrawString(drawString, printFont,
                                  brush, rectangle, tempFormat);
            col++;

            //列 名称
            drawString = saveTable.Rows[printIndex][3].ToString();
            //水平向右平移 并设置矩形框的宽度
            rectangle.X = cellLeft[col];
            rectangle.Width = cellWidth[col];
            e.Graphics.DrawString(drawString, printFont,
                brush, rectangle, tempFormat);
            col++;

            //列 设定值
            drawString = saveTable.Rows[printIndex][2].ToString();
            //水平向右平移 并设置矩形框的宽度
            rectangle.X = cellLeft[col];
            rectangle.Width = cellWidth[col];
            e.Graphics.DrawString(drawString, printFont,
                brush, rectangle, tempFormat);
            col++;

            //列 默认值
            drawString = saveTable.Rows[printIndex][4].ToString();
            //水平向右平移 并设置矩形框的宽度
            rectangle.X = cellLeft[col];
            rectangle.Width = cellWidth[col];
            e.Graphics.DrawString(drawString, printFont,
                brush, rectangle, tempFormat);
        }

PrintPage事件

计算每列占的比例,在事件中判断是否需要换页以及是否绘制结束。

   /// <summary>
        /// 当前页打印发生的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MyDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            //页面大小
            PaperSize pageSize = e.PageSettings.PaperSize;

            //根据页面大小,按比例划分列宽
            //序号
            cellWidth[0] = (float)(pageSize.Width * 0.098);
            //描述
            cellWidth[1] = (float)(pageSize.Width * 0.36);
            //当前值
            cellWidth[2] = (float)(pageSize.Width * 0.2);
            //出厂值
            cellWidth[3] = (float)(pageSize.Width * 0.1176);

            //计算列的起始位置
            cellLeft[0] = e.PageSettings.Margins.Left;
            cellLeft[1] = cellLeft[0] + cellWidth[0];
            cellLeft[2] = cellLeft[1] + cellWidth[1];
            cellLeft[3] = cellLeft[2] + cellWidth[2];

            //高度
            int tempTop = e.MarginBounds.Top;
            //是否新的页面
            bool tempIsNewPage = true;
           
            //设置打印字符串的格式
            StringFormat tempStrFormat = new StringFormat
            {
                Alignment = StringAlignment.Near,
                LineAlignment = StringAlignment.Center,
                Trimming = StringTrimming.EllipsisCharacter
            };

            //设置字体
            Font printFont = new Font("宋体", 9);
            //计算字体的高度
            int fontHeight = (int)e.Graphics.MeasureString("KK00.10序号", printFont).Height;

            //指定高质量、低速度呈现
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            try
            {
                string printStr;

                while(printPoint < saveTable.Rows.Count)
                {//逐行分页打印所有参数

                    if (tempTop + fontHeight > e.MarginBounds.Bottom)
                    {//判断当前打印是否超出页面范围,决定是否换页

                        //打印页脚
                        DrawFooter(e, PageNo);
                        PageNo++;
                        //继续分页打印
                        e.HasMorePages = true;
                        return;
                    }

                    //打印当前页的内容
                    //KK00.00
                    printStr = saveTable.Rows[printPoint][0].ToString().Substring(5);
                    if (printStr.Equals("00") || tempIsNewPage)
                    {//一组数据的开始
                        tempIsNewPage = false;
                        tempTop += 2;
                        //绘制标题
                        DrawTitle(e, tempTop, tempStrFormat);
                        tempTop += fontHeight;
                    }
                    
                        //绘制内容
                        DrawContent(e, printPoint, tempTop, tempStrFormat);
                        //更新Y轴高度
                        tempTop += fontHeight;

                    //序号自增
                    printPoint++;
                    //判断是否已经到终点
                    if(printPoint >= saveTable.Rows.Count)
                    {
                        //绘制页脚
                        DrawFooter(e, PageNo);
                        //重置打印参数
                        PageNo = 1;
                        printPoint = 0;
                        return;
                    }
                }
            }
            catch
            {
            }
        }

完整的代码工程

下面是完整的代码工程,设计界面的代码就不列出来了。

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.Windows.Forms;

namespace PrintDemo
{
    public partial class Form1 : Form
    {

        //打印序号
        int printPoint = 0;
        //页码
        int PageNo = 1;
        //表头名称
        string[] TitleStr = new string[]
        {
            "序号", "名称", "当前值", "出厂值"
        };

        //列宽
        float[] cellWidth = new float[4];
        //列左侧的起始位置
        float[] cellLeft = new float[4];

        //数据表
        DataTable saveTable;

        string fontName = "宋体";
        int fontNum = 9;


        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //数据
            saveTable = CreateTable();
            //打印预览按钮
            btnPreView.Click += BtnPreView_Click;
            //当前页打印发生的事件
            myDocument.PrintPage += MyDocument_PrintPage;
        }

     
        /// <summary>
        /// 构建临时数据表
        /// </summary>
        /// <returns></returns>
        private DataTable CreateTable()
        {
            DataTable dt = new DataTable();
            DataColumn col1 = new DataColumn("Num", typeof(string)); //序号
            DataColumn col2 = new DataColumn("Name", typeof(string)); //名称
            DataColumn col3 = new DataColumn("Val", typeof(string));  //当前值
            DataColumn col4 = new DataColumn("Des", typeof(string));  //描述
            DataColumn col5 = new DataColumn("Set", typeof(string)); //默认值

            dt.Columns.Add(col1);
            dt.Columns.Add(col2);
            dt.Columns.Add(col3);
            dt.Columns.Add(col4);
            dt.Columns.Add(col5);

            Random random = new Random();
            List<string> nameList = new List<string>
            {
                "A", "BB", "CCC", "D",
                "E", "F", "G","H","II",
                "JJ", "LL", "M"
            };

            List<string> tempList = new List<string>
            {
                "dsd", "sdfdgvre", "Hello", "Gilrs",
                "Today", "YYYY", "dfgre","GSD","fdgfer",
                "Wesd", "DLG", "fsdahfi;o"
            };

            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    DataRow dr = dt.NewRow();
                    //序号
                    dr[0] = "KK" + i.ToString("d2") + "." + j.ToString("d2");
                    //名称
                    dr[1] = nameList[j];

                    //当前值
                    if (j % 3 == 0)
                    {
                        dr[2] = random.NextDouble().ToString("f3");
                    }
                    else
                    {
                        dr[2] = i * j - random.Next(0, 30);
                    }
                    //描述
                    dr[3] = tempList[j];

                    //出厂值
                    dr[4] = random.NextDouble().ToString("f2");

                    //添加新行
                    dt.Rows.Add(dr);
                }
            }

            return dt;
        }


        /// <summary>
        /// 打印预览
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnPreView_Click(object sender, EventArgs e)
        {
            //打印预览对话框
            PrintPreviewDialog dialog = new PrintPreviewDialog();
            dialog.Document = myDocument;
            dialog.ShowIcon = false;
            dialog.ShowDialog();
        }

        /// <summary>
        /// 当前页打印发生的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MyDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            //页面大小
            PaperSize pageSize = e.PageSettings.PaperSize;

            //根据页面大小,按比例划分列宽
            //序号
            cellWidth[0] = (float)(pageSize.Width * 0.098);
            //描述
            cellWidth[1] = (float)(pageSize.Width * 0.36);
            //当前值
            cellWidth[2] = (float)(pageSize.Width * 0.2);
            //出厂值
            cellWidth[3] = (float)(pageSize.Width * 0.1176);

            //计算列的起始位置
            cellLeft[0] = e.PageSettings.Margins.Left;
            cellLeft[1] = cellLeft[0] + cellWidth[0];
            cellLeft[2] = cellLeft[1] + cellWidth[1];
            cellLeft[3] = cellLeft[2] + cellWidth[2];

            //高度
            int tempTop = e.MarginBounds.Top;
            //是否新的页面
            bool tempIsNewPage = true;
           
            //设置打印字符串的格式
            StringFormat tempStrFormat = new StringFormat
            {
                Alignment = StringAlignment.Near,
                LineAlignment = StringAlignment.Center,
                Trimming = StringTrimming.EllipsisCharacter
            };

            //设置字体
            Font printFont = new Font("宋体", 9);
            //计算字体的高度
            int fontHeight = (int)e.Graphics.MeasureString("KK00.10序号", printFont).Height;

            //指定高质量、低速度呈现
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            try
            {
                string printStr;

                while(printPoint < saveTable.Rows.Count)
                {//逐行分页打印所有参数

                    if (tempTop + fontHeight > e.MarginBounds.Bottom)
                    {//判断当前打印是否超出页面范围,决定是否换页

                        //打印页脚
                        DrawFooter(e, PageNo);
                        PageNo++;
                        //继续分页打印
                        e.HasMorePages = true;
                        return;
                    }

                    //打印当前页的内容
                    //KK00.00
                    printStr = saveTable.Rows[printPoint][0].ToString().Substring(5);
                    if (printStr.Equals("00") || tempIsNewPage)
                    {//一组数据的开始
                        tempIsNewPage = false;
                        tempTop += 2;
                        //绘制标题
                        DrawTitle(e, tempTop, tempStrFormat);
                        tempTop += fontHeight;
                    }
                    
                        //绘制内容
                        DrawContent(e, printPoint, tempTop, tempStrFormat);
                        //更新Y轴高度
                        tempTop += fontHeight;

                    //序号自增
                    printPoint++;
                    //判断是否已经到终点
                    if(printPoint >= saveTable.Rows.Count)
                    {
                        //绘制页脚
                        DrawFooter(e, PageNo);
                        //重置打印参数
                        PageNo = 1;
                        printPoint = 0;
                        return;
                    }
                }
            }
            catch
            {
            }
        }

        /// <summary>
        /// 绘制页脚
        /// </summary>
        /// <param name="e">绘图对象</param>
        /// <param name="pageNo">页面序号</param>
        private void DrawFooter(System.Drawing.Printing.PrintPageEventArgs e, int pageNo)
        {
            Font font = new Font("微软雅黑", 10);

            //绘制直线
            e.Graphics.DrawLine(new Pen(Color.Black, 1),
                new Point(e.MarginBounds.Left, e.MarginBounds.Bottom),
                new Point(e.MarginBounds.Right, e.MarginBounds.Bottom));

            //公司信息标注
            string tempStr = "Test for Windows(C) by 唠嗑一夏 Electric Corporation";

            e.Graphics.DrawString(tempStr,
              font, Brushes.Black,
              e.MarginBounds.Left,
              e.MarginBounds.Bottom+2);
            
            //页脚序号
            tempStr = pageNo.ToString();
            e.Graphics.DrawString(tempStr,
                font, Brushes.Black,
                e.MarginBounds.Right -  e.Graphics.MeasureString(tempStr, font).Width,
                e.MarginBounds.Bottom+2);
        }


        /// <summary>
        /// 绘制标题头
        /// </summary>
        /// <param name="e">绘图对象</param>
        /// <param name="tempTop">Y轴坐标</param>
        /// <param name="tempFormat">字符串格式</param>
        private void DrawTitle(System.Drawing.Printing.PrintPageEventArgs e,
            int tempTop, StringFormat tempFormat)
        {
            //绘制水平线
            e.Graphics.DrawLine(Pens.Black,
                new Point(e.MarginBounds.Left, tempTop),
                new Point(e.MarginBounds.Right, tempTop));

            Font printFont = new Font(fontName, fontNum);

            //计算字体的高度 K00ARk, 根据使用到的字进行组合成串
            int fontHeight = (int)(e.Graphics.MeasureString("K00ARk", printFont).Height);

            //画刷
            SolidBrush brush = new SolidBrush(Color.Black);

            //填充背景色
            e.Graphics.FillRectangle(Brushes.LightBlue,
                new RectangleF(e.MarginBounds.Left, tempTop, e.MarginBounds.Width, fontHeight));


            //列的序号
            int col = 0;

            //列 序号
            string drawString = TitleStr[col];
            //矩形框
            RectangleF rectangle = new RectangleF((int)cellLeft[col], tempTop,
                                       (int)cellWidth[col], fontHeight);

            e.Graphics.DrawString(drawString, printFont,
                                  brush, rectangle, tempFormat);
            col++;

            //列 名称
            drawString = TitleStr[col];
            //水平向右平移 并设置矩形框的宽度
            rectangle.X = cellLeft[col];
            rectangle.Width = cellWidth[col];
            e.Graphics.DrawString(drawString, printFont,
                brush, rectangle, tempFormat);
            col++;

            //列 设定值
            drawString = TitleStr[col];
            //水平向右平移 并设置矩形框的宽度
            rectangle.X = cellLeft[col];
            rectangle.Width = cellWidth[col];
            e.Graphics.DrawString(drawString, printFont,
                brush, rectangle, tempFormat);
            col++;

            //列 默认值
            drawString = TitleStr[col];
            //水平向右平移 并设置矩形框的宽度
            rectangle.X = cellLeft[col];
            rectangle.Width = cellWidth[col];
            e.Graphics.DrawString(drawString, printFont,
                brush, rectangle, tempFormat);
        }

        /// <summary>
        /// 绘制内容
        /// </summary>
        ///  <param name="e">绘图对象</param>
        ///  <param name="printIndex">数据行索引</param>
        /// <param name="tempTop">Y轴坐标</param>
        /// <param name="tempFormat">字符串格式</param>
        private void DrawContent(System.Drawing.Printing.PrintPageEventArgs e, 
                     int printIndex, int tempTop, StringFormat tempFormat)
        {
            Font printFont = new Font(fontName, fontNum);

            //计算字体的高度 K00ARk, 根据使用到的字进行组合成串
            int fontHeight = (int)(e.Graphics.MeasureString("K00ARk", printFont).Height);

            //画刷
            SolidBrush brush = new SolidBrush(Color.Black);

            //列的序号
            int col = 0;

            //列 序号
            string drawString = saveTable.Rows[printIndex][0].ToString() + saveTable.Rows[printIndex][1].ToString();
             //矩形框
            RectangleF rectangle = new RectangleF((int)cellLeft[col], tempTop,
                                       (int)cellWidth[col], fontHeight);

            e.Graphics.DrawString(drawString, printFont,
                                  brush, rectangle, tempFormat);
            col++;

            //列 名称
            drawString = saveTable.Rows[printIndex][3].ToString();
            //水平向右平移 并设置矩形框的宽度
            rectangle.X = cellLeft[col];
            rectangle.Width = cellWidth[col];
            e.Graphics.DrawString(drawString, printFont,
                brush, rectangle, tempFormat);
            col++;

            //列 设定值
            drawString = saveTable.Rows[printIndex][2].ToString();
            //水平向右平移 并设置矩形框的宽度
            rectangle.X = cellLeft[col];
            rectangle.Width = cellWidth[col];
            e.Graphics.DrawString(drawString, printFont,
                brush, rectangle, tempFormat);
            col++;

            //列 默认值
            drawString = saveTable.Rows[printIndex][4].ToString();
            //水平向右平移 并设置矩形框的宽度
            rectangle.X = cellLeft[col];
            rectangle.Width = cellWidth[col];
            e.Graphics.DrawString(drawString, printFont,
                brush, rectangle, tempFormat);
        }

    }
}

最后的效果图
在这里插入图片描述
在这里插入图片描述

小节

1 使用PrintPreviewDialog + PrintDocument 可以实现打印预览功能

2 页面的绘制是在PrintDocument 的PrintDocument.PrintPage打印页事件中绘制

3 System.Drawing.Printing.PrintPageEventArgs e 在 e.Graphics的画布上进行绘制,DrawString绘制文本,DrawLine绘制直线,FillRectangle填充背景色,根据实际需要选择相应的接口。

4 绘制需要注意绘制点的X Y 坐标,可以以页面的边距e.MarginBounds作为参考点,使用e.Graphics.MeasureString可以测量该字符串占用的高和宽。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。