zoukankan      html  css  js  c++  java
  • C# 使用PrintDocument 绘制表格 完成 打印预览 DataTable

    经过不断的Google与baidu,最终整理出来的打印类

    主要是根据两个参考的类组合而成,稍微修改了一下,参考代码及来源见最后(其中一份是VB语言的)

    其中遇到的一些问题也已经得到了解决(分页,打印预览点击打印内容缺失)

    ------------------------------------------------------------------------------

    相关知识

    PrintDocument

    定义一个可再次使用的对象,该对象将输出发送到打印机。

    命名空间:System.Drawing.Printing
    程序集:System.Drawing(在 system.drawing.dll 中)

    通常可以创建 PrintDocument 类的实例,设置描述打印方式的属性,然后调用 Print 方法开始打印进程。通过使用 PrintPageEventArgs 中包含的 Graphics 来处理用于指定打印输出的 PrintPage 事

    PrintDocument.PrintPage 事件

    当需要为当前页打印的输出时发生。

    PrintDocument.Print 方法

    开始文档的打印进程。

    PrintPageEventArgs.HasMorePages 

    获取或设置一个值,该值指示是否打印附加页。

    以上摘自:http://msdn.microsoft.com/zh-cn/library/system.drawing.printing.printdocument(v=VS.80).aspx

    ---------------------------

    打印类

    using System.Drawing;
    using System.Drawing.Printing;
    using System.Windows.Forms;
    using System.Data;
    using System;
    
    /// <summary>
    /// 打印,打印预览
    /// 唐小熊 2013-08-01
    /// </summary>
    public class ToPrint
    {
    
        //以下用户可自定义
        //当前要打印文本的字体及字号
        private static Font TableFont = new Font("Verdana", 10, FontStyle.Regular);
        //表头字体
        private Font HeadFont = new Font("Verdana", 20, FontStyle.Bold);
        //表头文字
        private string HeadText = string.Empty;
        //表头高度
        private int HeadHeight = 40;
        //表的基本单位
        private int[] XUnit;
        private int YUnit = TableFont.Height * 2;
        //以下为模块内部使用
        private PrintDocument DataTablePrinter;
        private DataRow DataGridRow;
        private DataTable DataTablePrint;
        //当前要所要打印的记录行数,由计算得到
        private int PageRecordNumber;
        //正要打印的页号
        private int PrintingPageNumber = 1;
        //已经打印完的记录数
        private int PrintRecordComplete;
        private int PLeft;
        private int PTop;
        private int PRight;
        private int PBottom;
        private int PWidth;
        private int PHeigh;
        //当前画笔颜色
        private SolidBrush DrawBrush = new SolidBrush(Color.Black);
        //每页打印的记录条数
        private int PrintRecordNumber;
        //第一页打印的记录条数
        private int FirstPrintRecordNumber;
        //总共应该打印的页数
        private int TotalPage;
        //与列名无关的统计数据行的类目数(如,总计,小计......)
        public int TotalNum = 0;
    
        /// <summary>
        /// 打印
        /// </summary>
        /// <param name="dt">要打印的DataTable</param>
        /// <param name="Title">打印文件的标题</param>
        public void Print(DataTable dt, string Title)
        {
            try
            {
                CreatePrintDocument(dt, Title).Print();
            }
            catch (Exception ex)
            {
                MessageBox.Show("打印错误,请检查打印设置!");
    
            }
        }
    
        /// <summary>
        /// 打印预览
        /// </summary>
        /// <param name="dt">要打印的DataTable</param>
        /// <param name="Title">打印文件的标题</param>
        public void PrintPriview(DataTable dt, string Title)
        {
            try
            {
                PrintPreviewDialog PrintPriview = new PrintPreviewDialog();
                PrintPriview.Document = CreatePrintDocument(dt, Title);
                PrintPriview.WindowState = FormWindowState.Maximized;
                PrintPriview.ShowDialog();
            }
            catch (Exception ex)
            {
                MessageBox.Show("打印错误,请检查打印设置!");
    
            }
        }
    
        /// <summary>
        /// 创建打印文件
        /// </summary>
        private PrintDocument CreatePrintDocument(DataTable dt, string Title)
        {
    
            DataTablePrint = dt;
            HeadText = Title;
            DataTablePrinter = new PrintDocument();
    
            PageSetupDialog PageSetup = new PageSetupDialog();
            PageSetup.Document = DataTablePrinter;
            DataTablePrinter.DefaultPageSettings = PageSetup.PageSettings;
            DataTablePrinter.DefaultPageSettings.Landscape = true;//设置打印横向还是纵向
            //PLeft = 30; //DataTablePrinter.DefaultPageSettings.Margins.Left;
            PTop = DataTablePrinter.DefaultPageSettings.Margins.Top;
            //PRight = DataTablePrinter.DefaultPageSettings.Margins.Right;
            PBottom = DataTablePrinter.DefaultPageSettings.Margins.Bottom;
            PWidth = DataTablePrinter.DefaultPageSettings.Bounds.Width;
            PHeigh = DataTablePrinter.DefaultPageSettings.Bounds.Height;
            XUnit = new int[DataTablePrint.Columns.Count];
            PrintRecordNumber = Convert.ToInt32((PHeigh - PTop - PBottom - YUnit) / YUnit);
            FirstPrintRecordNumber = Convert.ToInt32((PHeigh - PTop - PBottom - HeadHeight - YUnit) / YUnit);
    
            if (DataTablePrint.Rows.Count > PrintRecordNumber)
            {
                if ((DataTablePrint.Rows.Count - FirstPrintRecordNumber) % PrintRecordNumber == 0)
                {
                    TotalPage = (DataTablePrint.Rows.Count - FirstPrintRecordNumber) / PrintRecordNumber + 1;
                }
                else
                {
                    TotalPage = (DataTablePrint.Rows.Count - FirstPrintRecordNumber) / PrintRecordNumber + 2;
                }
            }
            else
            {
                TotalPage = 1;
            }
     
            DataTablePrinter.PrintPage += new PrintPageEventHandler(DataTablePrinter_PrintPage);
            DataTablePrinter.DocumentName = HeadText;
    
            return DataTablePrinter;
        }
    
        /// <summary>
        /// 打印当前页
        /// </summary>
        private void DataTablePrinter_PrintPage(object sende, PrintPageEventArgs Ev)
        {
    
    
            int tableWith = 0;
            string ColumnText;
    
            StringFormat sf = new StringFormat();
            sf.Alignment = StringAlignment.Center;
    
            //打印表格线格式
            Pen Pen = new Pen(Brushes.Black, 1);
    
            #region 设置列宽
    
            foreach (DataRow dr in DataTablePrint.Rows)
            {
                for (int i = 0; i < DataTablePrint.Columns.Count; i++)
                {
                    int colwidth = Convert.ToInt32(Ev.Graphics.MeasureString(dr[i].ToString().Trim(), TableFont).Width);
                    if (colwidth > XUnit[i])
                    {
                        XUnit[i] = colwidth;
                    }
                }
            }
    
            if (PrintingPageNumber == 1)
            {
                for (int Cols = 0; Cols <= DataTablePrint.Columns.Count - 1; Cols++)
                {
                    ColumnText = DataTablePrint.Columns[Cols].ColumnName.ToString().Trim();
                    int colwidth = Convert.ToInt32(Ev.Graphics.MeasureString(ColumnText, TableFont).Width);
                    if (colwidth > XUnit[Cols])
                    {
                        XUnit[Cols] = colwidth;
                    }
                }
            }
            for (int i = 0; i < XUnit.Length; i++)
            {
                tableWith += XUnit[i];
            }
            #endregion
    
            PLeft = (Ev.PageBounds.Width - tableWith) / 2;
            int x = PLeft;
            int y = PTop;
            int stringY = PTop + (YUnit - TableFont.Height) / 2;
            int rowOfTop = PTop;
    
            //第一页
            if (PrintingPageNumber == 1)
            {
                //打印表头
                Ev.Graphics.DrawString(HeadText, HeadFont, DrawBrush, new Point(Ev.PageBounds.Width / 2, PTop), sf);
    
    
                //设置为第一页时行数
                PageRecordNumber = FirstPrintRecordNumber;
                rowOfTop = y = PTop + HeadFont.Height + 10;
                stringY = PTop + HeadFont.Height + 10 + (YUnit - TableFont.Height) / 2;
            }
            else
            {
                //计算,余下的记录条数是否还可以在一页打印,不满一页时为假
                if (DataTablePrint.Rows.Count - PrintRecordComplete >= PrintRecordNumber)
                {
                    PageRecordNumber = PrintRecordNumber;
                }
                else
                {
                    PageRecordNumber = DataTablePrint.Rows.Count - PrintRecordComplete;
                }
            }
    
            #region 列名
            if (PrintingPageNumber == 1 || PageRecordNumber > TotalNum)//最后一页只打印统计行时不打印列名
            {
                //得到datatable的所有列名
                for (int Cols = 0; Cols <= DataTablePrint.Columns.Count - 1; Cols++)
                {
                    ColumnText = DataTablePrint.Columns[Cols].ColumnName.ToString().Trim();
    
                    int colwidth = Convert.ToInt32(Ev.Graphics.MeasureString(ColumnText, TableFont).Width);
                    Ev.Graphics.DrawString(ColumnText, TableFont, DrawBrush, x, stringY);
                    x += XUnit[Cols];
                }
            }
            #endregion
    
    
    
            Ev.Graphics.DrawLine(Pen, PLeft, rowOfTop, x, rowOfTop);
            stringY += YUnit;
            y += YUnit;
            Ev.Graphics.DrawLine(Pen, PLeft, y, x, y);
    
            //当前页面已经打印的记录行数
            int PrintingLine = 0;
            while (PrintingLine < PageRecordNumber)
            {
                x = PLeft;
                //确定要当前要打印的记录的行号
                DataGridRow = DataTablePrint.Rows[PrintRecordComplete];
                for (int Cols = 0; Cols <= DataTablePrint.Columns.Count - 1; Cols++)
                {
                    Ev.Graphics.DrawString(DataGridRow[Cols].ToString().Trim(), TableFont, DrawBrush, x, stringY);
                    x += XUnit[Cols];
                }
                stringY += YUnit;
                y += YUnit;
                Ev.Graphics.DrawLine(Pen, PLeft, y, x, y);
    
                PrintingLine += 1;
                PrintRecordComplete += 1;
                if (PrintRecordComplete >= DataTablePrint.Rows.Count)
                {
                    Ev.HasMorePages = false;
                    PrintRecordComplete = 0;
                }
            }
    
            Ev.Graphics.DrawLine(Pen, PLeft, rowOfTop, PLeft, y);
            x = PLeft;
            for (int Cols = 0; Cols < DataTablePrint.Columns.Count; Cols++)
            {
                x += XUnit[Cols];
                Ev.Graphics.DrawLine(Pen, x, rowOfTop, x, y);
            }
    
    
    
            PrintingPageNumber += 1;
    
            if (PrintingPageNumber > TotalPage)
            {
                Ev.HasMorePages = false;
                PrintingPageNumber = 1;
                PrintRecordComplete = 0;
            }
            else
            {
                Ev.HasMorePages = true;
            }
    
    
        }
    
    }

    打印多页时 要根据剩余页数判断并设置 HasMorePages 是否继续执行 PrintPage

    打印预览中点击打印按钮,实际上会再次执行 PrintPage 事件,所以再打印完文档后 应该对相关属性进行重置

     if (PrintingPageNumber > TotalPage)
     {
        Ev.HasMorePages = false;
        PrintingPageNumber = 1;
        PrintRecordComplete = 0;
     }
     else
     {
        Ev.HasMorePages = true;
     }

    参考代码如下(或者说是复制的原本 ^_^)

    版本一(VB)

    来自 :http://bbs.csdn.net/topics/340132124 printdocument控件如何绘制表格?

    Imports System.Drawing
    Imports System.Drawing.Pen
    Imports System.Drawing.Font
    Imports System.Drawing.PointF
    Imports System.Drawing.Color
    Imports System.Drawing.Printing
    Imports System.Windows.Forms
    Imports System.Windows.Forms.DataGrid
    
    Public Class PrintDataTable
        '以下用户可自定义
        '当前要打印文本的字体及字号
        Private TableFont As New Font("宋体", 10)
        '表头字体
        Private HeadFont As New Font("宋体", 20, FontStyle.Bold)
        '副表头字体
        Private SubHeadFont As New Font("宋体", 10, FontStyle.Regular)
        '表头文字
        Private HeadText As String
        '副表头左文字
        Private SubHeadLeftText As String
        '副表头右文字
        Private SubHeadRightText As String
        '表头高度
        Private HeadHeight As Integer = 40
        '副表头高度
        Private SubHeadHeight As Integer = 20
        '表脚字体
        Private FootFont As New Font("宋体", 10, FontStyle.Regular)
        '副表脚字体
        Private SubFootFont As New Font("宋体", 10, FontStyle.Regular)
        '表脚文字
        Private FootText As String
        '副表脚左文字
        Private SubFootLeftText As String
        '副表脚右文字
        Private SubFootRightText As String
        '表脚高度
        Private FootHeight As Integer = 30
        '副表脚高度
        Private SubFootHeight As Integer = 20
        '表的基本单位
        Dim XUnit As Integer
        Dim YUnit As Integer = TableFont.Height * 2.5
        '以下为模块内部使用
        Private Ev As PrintPageEventArgs
        Private DataTablePrinter As PrintDocument
        Private DataGridColumn As DataColumn
        Private DataGridRow As DataRow
        Private DataTablePrint As DataTable
        '当前要打印的行
        Private Rows As Integer
        '当前DATAGRID共有多少列
        Private ColsCount As Integer
        '当前正要打印的行号
        Private PrintingLineNumber As Integer
        '当前要所要打印的记录行数,由计算得到
        Private PageRecordNumber As Integer
        '正要打印的页号
        Private PrintingPageNumber As Integer
        '共需要打印的页数
        Private PageNumber As Integer
        '当前还有多少页没有打印
        Private PrintRecordLeave As Integer
        '已经打印完的记录数
        Private PrintRecordComplete As Integer
        Private PLeft As Integer
        Private PTop As Integer
        Private PRight As Integer
        Private PBottom As Integer
        Private PWidth As Integer
        Private PHeigh As Integer
        '当前画笔颜色
        Private DrawBrush As New SolidBrush(System.Drawing.Color.Black)
        '每页打印的记录条数
        Private PrintRecordNumber As Integer
        '总共应该打印的页数
        Private TotalPage As Integer
    
        Sub New(ByVal TableSource As DataTable)
            DataTablePrint = New DataTable
            DataTablePrint = TableSource
            ColsCount = DataTablePrint.Columns.Count
        End Sub
    
        '用户自定义字体及字号
        Public WriteOnly Property SetTableFont() As System.Drawing.Font
            Set(ByVal Value As System.Drawing.Font)
                TableFont = Value
            End Set
        End Property
    
        Public WriteOnly Property SetHeadFont() As System.Drawing.Font
            Set(ByVal Value As System.Drawing.Font)
                HeadFont = Value
            End Set
        End Property
    
        Public WriteOnly Property SetSubHeadFont() As System.Drawing.Font
            Set(ByVal Value As System.Drawing.Font)
                SubHeadFont = Value
            End Set
        End Property
    
        Public WriteOnly Property SetFootFont() As System.Drawing.Font
            Set(ByVal Value As System.Drawing.Font)
                FootFont = Value
            End Set
        End Property
    
        Public WriteOnly Property SetSubFootFont() As System.Drawing.Font
            Set(ByVal Value As System.Drawing.Font)
                SubFootFont = Value
            End Set
        End Property
    
        Public WriteOnly Property SetHeadText() As String
            Set(ByVal Value As String)
                HeadText = Value
            End Set
        End Property
    
        Public WriteOnly Property SetSubHeadLeftText() As String
            Set(ByVal Value As String)
                SubHeadLeftText = Value
            End Set
        End Property
    
        Public WriteOnly Property SetSubHeadRightText() As String
            Set(ByVal Value As String)
                SubHeadRightText = Value
            End Set
        End Property
    
        Public WriteOnly Property SetFootText() As String
            Set(ByVal Value As String)
                FootText = Value
            End Set
        End Property
    
        Public WriteOnly Property SetSubFootLeftText() As String
            Set(ByVal Value As String)
                SubFootLeftText = Value
            End Set
        End Property
    
        Public WriteOnly Property SetSubFootRightText() As String
            Set(ByVal Value As String)
                SubFootRightText = Value
            End Set
        End Property
    
        Public WriteOnly Property SetHeadHeight() As Integer
            Set(ByVal Value As Integer)
                HeadHeight = Value
            End Set
        End Property
    
        Public WriteOnly Property SetSubHeadHeight() As Integer
            Set(ByVal Value As Integer)
                SubHeadHeight = Value
            End Set
        End Property
    
        Public WriteOnly Property SetFootHeight() As Integer
            Set(ByVal Value As Integer)
                FootHeight = Value
            End Set
        End Property
    
        Public WriteOnly Property SetSubFootHeight() As Integer
            Set(ByVal Value As Integer)
                SubFootHeight = Value
            End Set
        End Property
    
        Public WriteOnly Property SetCellHeight() As Integer
            Set(ByVal Value As Integer)
                YUnit = Value
            End Set
        End Property
    
        Public Sub Print()
            Try
                DataTablePrinter = New Printing.PrintDocument
                AddHandler DataTablePrinter.PrintPage, AddressOf DataTablePrinter_PrintPage
                Dim PageSetup As PageSetupDialog
                PageSetup = New PageSetupDialog
                PageSetup.Document = DataTablePrinter
                DataTablePrinter.DefaultPageSettings = PageSetup.PageSettings
                If PageSetup.ShowDialog() = DialogResult.Cancel Then
                    Exit Sub
                End If
                PLeft = DataTablePrinter.DefaultPageSettings.Margins.Left
                PTop = DataTablePrinter.DefaultPageSettings.Margins.Top
                PRight = DataTablePrinter.DefaultPageSettings.Margins.Right
                PBottom = DataTablePrinter.DefaultPageSettings.Margins.Bottom
                PWidth = DataTablePrinter.DefaultPageSettings.Bounds.Width
                PHeigh = DataTablePrinter.DefaultPageSettings.Bounds.Height
                '将当前页分成基本的单元
                XUnit = (PWidth - PLeft - PRight) / DataTablePrint.Columns.Count - 1
                PrintRecordNumber = (PHeigh - PTop - PBottom - HeadHeight - SubHeadHeight - FootHeight - SubFootHeight - YUnit)  YUnit
                If DataTablePrint.Rows.Count > PrintRecordNumber Then
                    If DataTablePrint.Rows.Count Mod PrintRecordNumber = 0 Then
                        TotalPage = DataTablePrint.Rows.Count  PrintRecordNumber
                    Else
                        TotalPage = DataTablePrint.Rows.Count  PrintRecordNumber + 1
                    End If
                Else
                    TotalPage = 1
                End If
                DataTablePrinter.DocumentName = TotalPage.ToString
                Dim PrintPriview As PrintPreviewDialog
                PrintPriview = New PrintPreviewDialog
                PrintPriview.Document = DataTablePrinter
                PrintPriview.WindowState = FormWindowState.Maximized
                PrintPriview.ShowDialog()
            Catch ex As Exception
                MsgBox("打印错误,请检查打印设置!", 16, "错误")
            End Try
        End Sub
    
    
    
        Private Sub DataTablePrinter_PrintPage(ByVal sender As Object, ByVal Ev As System.Drawing.Printing.PrintPageEventArgs)
            '还有多少条记录没有打印
            PrintRecordLeave = DataTablePrint.Rows.Count - PrintRecordComplete
            If PrintRecordLeave > 0 Then
                If PrintRecordLeave Mod PrintRecordNumber = 0 Then
                    PageNumber = PrintRecordLeave  PrintRecordNumber
                Else
                    PageNumber = PrintRecordLeave  PrintRecordNumber + 1
                End If
            Else
                PageNumber = 0
            End If
            '正在打印的页数,因为每打印一个新页都要计算还有多少页没有打印所以以打印的页数初始为0
            PrintingPageNumber = 0
            '计算,余下的记录条数是否还可以在一页打印,不满一页时为假
            If DataTablePrint.Rows.Count - PrintingPageNumber * PrintRecordNumber >= PrintRecordNumber Then
                PageRecordNumber = PrintRecordNumber
            Else
                PageRecordNumber = (DataTablePrint.Rows.Count - PrintingPageNumber * PrintRecordNumber) Mod PrintRecordNumber
            End If
            Dim fmt As New StringFormat
            '上下对齐
            fmt.LineAlignment = StringAlignment.Center
            '自动换行
            fmt.FormatFlags = StringFormatFlags.LineLimit
            '打印区域
            Dim Rect As New Rectangle
            '打印表格线格式
            Dim Pen As New Pen(Brushes.Black, 1)
            While PrintingPageNumber <= PageNumber
                '表头中间对齐
                fmt.Alignment = StringAlignment.Center
                '表头和副表头宽度等于设置区域宽度
                Rect.Width = PWidth - PLeft - PRight
                Rect.Height = HeadHeight
                Rect.X = PLeft
                Rect.Y = PTop
                '打印表头
                Ev.Graphics.DrawString(HeadText, HeadFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
                '副表头左对齐
                fmt.Alignment = StringAlignment.Near
                Rect.Width = (PWidth - PLeft - PRight) / 2 - 1
                Rect.Height = SubHeadHeight
                Rect.Y = PTop + HeadHeight
                '打印副表头左
                Ev.Graphics.DrawString(SubHeadLeftText, SubHeadFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
                '右副表头文字从右往左排列
                fmt.FormatFlags = StringFormatFlags.DirectionRightToLeft
                '右副表头右对齐
                fmt.Alignment = StringAlignment.Near
                Rect.X = PLeft + (PWidth - PLeft - PRight) / 2
                '打印副表头右
                Ev.Graphics.DrawString(SubHeadRightText, SubHeadFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
                fmt.Alignment = StringAlignment.Center
                Rect.X = PLeft
                Rect.Y = PTop + HeadHeight + SubHeadHeight + (PrintRecordNumber + 1) * (YUnit) + SubFootHeight
                Rect.Height = FootHeight
                Rect.Width = PWidth - PLeft - PRight
                '打印表脚
                Ev.Graphics.DrawString(FootText, FootFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
                '副表左左对齐
                fmt.Alignment = StringAlignment.Far
                Rect.X = PLeft
                Rect.Y = PTop + HeadHeight + SubHeadHeight + (PrintRecordNumber + 1) * (YUnit)
                Rect.Height = SubFootHeight
                Rect.Width = (PWidth - PLeft - PRight) / 2 - 1
                '打印左表脚
                Ev.Graphics.DrawString(SubFootLeftText, SubFootFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
                '副表头右对齐
                fmt.Alignment = StringAlignment.Near
                Rect.X = PLeft + (PWidth - PLeft - PRight) / 2
                If DataTablePrint.Rows.Count = 0 Then
                    SubFootRightText = "" & TotalPage & "页,共" & TotalPage & ""
                Else
                    SubFootRightText = "" & TotalPage - PageNumber + 1 & "页,共" & TotalPage & ""
                End If
                '打印右表脚
                Ev.Graphics.DrawString(SubFootRightText, SubFootFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
                '得到datatable的所有列名
                fmt.Alignment = StringAlignment.Center
                Dim ColumnText(DataTablePrint.Columns.Count) As String
                For Cols = 0 To DataTablePrint.Columns.Count - 1
                    '得到当前所有的列名
                    ColumnText(Cols) = DataTablePrint.Columns(Cols).ToString
                    Rect.X = PLeft + XUnit * Cols
                    Rect.Y = PTop + HeadHeight + SubHeadHeight
                    Rect.Width = XUnit
                    Rect.Height = YUnit
                    Ev.Graphics.DrawString(ColumnText(Cols), New Font(TableFont, FontStyle.Bold), DrawBrush, RectangleF.op_Implicit(Rect), fmt)
                    Ev.Graphics.DrawRectangle(Pen, Rect)
                Next
                '结束---------------------得到datatable的所有列名
                '当前页面已经打印的记录行数
                Dim PrintingLine As Integer = 0
                While PrintingLine < PageRecordNumber
                    '确定要当前要打印的记录的行号
                    DataGridRow = DataTablePrint.Rows(PrintRecordComplete)
                    For Cols = 0 To DataTablePrint.Columns.Count - 1
                        Rect.X = PLeft + XUnit * Cols
                        Rect.Y = PTop + HeadHeight + SubHeadHeight + (PrintingLine + 1) * (YUnit)
                        Rect.Width = XUnit
                        Rect.Height = YUnit
                        If DataGridRow(ColumnText(Cols)) Is System.DBNull.Value = False Then
                            Ev.Graphics.DrawString(DataGridRow(ColumnText(Cols)), TableFont, DrawBrush, RectangleF.op_Implicit(Rect), fmt)
                        End If
                        Ev.Graphics.DrawRectangle(Pen, Rect)
                    Next
                    PrintingLine += 1
                    PrintRecordComplete += 1
                    If PrintRecordComplete >= DataTablePrint.Rows.Count Then
                        Ev.HasMorePages = False
                        PrintRecordComplete = 0
                        Exit Sub
                    End If
                End While
                PrintingPageNumber += 1
                If PrintingPageNumber >= PageNumber Then
                    Ev.HasMorePages = False
                Else
                    Ev.HasMorePages = True
                    Exit While
                End If
            End While
        End Sub
    
        '附转换函数
        'listview转为Datatable函数
        Public Function ListviewToDatatable(ByVal Listview1 As ListView)
            Dim Table1 As New DataTable
            Dim i As Integer
            Dim datacol As DataColumn
            For i = 0 To Listview1.Columns.Count - 1
                datacol = New DataColumn
                datacol.DataType = Type.GetType("System.Object")
                datacol.ColumnName = Listview1.Columns(i).Text.Trim
                Table1.Columns.Add(datacol)
            Next i
            Dim j As Integer
            Dim Datarow1 As DataRow
            For j = 0 To Listview1.Items.Count - 1
                Datarow1 = Table1.NewRow
                For i = 0 To Listview1.Columns.Count - 1
                    Datarow1.Item(Listview1.Columns(i).Text.Trim) = Listview1.Items(j).SubItems(i).Text.ToString
                Next i
                Table1.Rows.Add(Datarow1)
            Next j
            Return Table1
        End Function
    
        '数据集转为Datatable函数
        Public Function DataBaseToDataTable(ByVal SqlDataAdapter1 As Data.SqlClient.SqlDataAdapter, ByVal TableName As String)
            Dim Table1 As New DataTable
            Dim DataSet1 As New DataSet
            DataSet1.Clear()
            SqlDataAdapter1.Fill(DataSet1, TableName)
            Table1 = DataSet1.Tables(TableName)
            Return Table1
        End Function
    End Class
    
    
    
    Public Class FormPrintDataTable
    
        Private Sub ButtonClickMe_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonClickMe.Click
            Dim SqlConn As New OleDb.OleDbConnection
            Dim SqlCmd As New OleDb.OleDbCommand
            Dim SqlAda As New OleDb.OleDbDataAdapter
            Dim Dt As New DataTable
            SqlConn.ConnectionString = "provider=microsoft.jet.oledb.4.0;data source=" & Application.StartupPath & "datadata.mdb"
            SqlCmd.Connection = SqlConn
            SqlCmd.CommandText = "select * from [CARD]"
            SqlConn.Open()
            SqlAda.SelectCommand = SqlCmd
            SqlAda.Fill(Dt)
            SqlCmd.Cancel()
            SqlConn.Close()
            Dim PDt As New PrintDataTable(Dt)
            PDt.SetHeadText = "XXXX煤矿报表测试"
            PDt.SetFootText = "矿长签字:             总工签字:             值班人员签字:"
            PDt.SetSubHeadLeftText = "数据时间:" & Now.Date
            PDt.SetSubHeadRightText = "打印时间:" & Now.Date
            PDt.Print()
        End Sub
    End Class

    版本二 C# 打印DataTable 来自 http://blog.csdn.net/lee576/article/details/3352335

    public class PrintFunction
        {
            public String printName = String.Empty;
            public Font prtTextFont = new Font("Verdana", 10);
            public Font prtTitleFont = new Font("宋体", 10);
            private String[] titles = new String[0]; 
            public String[] Titles
            {
                set
                {
                    titles = value as String[];
                    if (null == titles)
                    {
                        titles = new String[0];
                    }
                }
                get
                {
                    return titles;
                }
            }
            private Int32 left = 20;
            private Int32 top = 20;
            public Int32 Top
            {
                set
                {
                    top = value;                
                }
                get
                {
                    return top;
                }
            }
            public Int32 Left
            {
                set
                {
                    left = value;
                }
                get
                {
                    return left;
                }
            }
            private DataTable printedTable;
            private Int32 pheight;
            private Int32 pWidth;
            private Int32 pindex;
            private Int32 curdgi;
            private Int32[] width;
            private Int32 rowOfDownDistance = 3;
            private Int32 rowOfUpDistance = 2;
            public Boolean PrintDataTable(DataTable table)
            {
                PrintDocument prtDocument = new PrintDocument();
                try
                {
                    if (printName != String.Empty)
                    {
                        prtDocument.PrinterSettings.PrinterName = printName;
                    }
                    prtDocument.DefaultPageSettings.Landscape = true;
                    prtDocument.OriginAtMargins = false;
                    PrintDialog prtDialog = new PrintDialog();
                    prtDialog.AllowSomePages = true;
    
                    prtDialog.ShowHelp = false;
                    prtDialog.Document = prtDocument;
    
                    if (DialogResult.OK != prtDialog.ShowDialog())
                    {
                        return false;
                    }
    
                    printedTable = table;
                    pindex = 0;
                    curdgi = 0;
                    width = new Int32[printedTable.Columns.Count];
                    pheight = prtDocument.PrinterSettings.DefaultPageSettings.Bounds.Bottom;
                    pWidth = prtDocument.PrinterSettings.DefaultPageSettings.Bounds.Right;
    
                    prtDocument.PrintPage += new PrintPageEventHandler(Document_PrintPage);
    
                    prtDocument.Print();
    
                }
                catch( InvalidPrinterException ex )
                {
                    MessageBox.Show("没有安装打印机");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("打印错误");
                }
                prtDocument.Dispose();
                return true;
            }
    
            Int32 startColumnControls = 0;
            Int32 endColumnControls = 0;
            private void Document_PrintPage(object sender, PrintPageEventArgs ev)
            {
                Int32 x = left;
                Int32 y = top;
                Int32 rowOfTop = top;
                Int32 i;
                Pen pen = new Pen(Brushes.Black, 1);
                if (0 == pindex)
                {
                    for (i = 0; i < titles.Length; i++)
                    {
                        ev.Graphics.DrawString(titles[i], prtTitleFont, Brushes.Black, left, y + rowOfUpDistance);
                        y += prtTextFont.Height + rowOfDownDistance;
                    }
                    rowOfTop = y;
                    foreach(DataRow dr in printedTable.Rows)
                    {
                        for (i = 0; i < printedTable.Columns.Count; i++)
                        {
                            Int32 colwidth = Convert.ToInt16(ev.Graphics.MeasureString(dr[i].ToString().Trim(), prtTextFont).Width);
                            if (colwidth>width[i])
                            {
                                width[i] = colwidth;
                            }
                        }
                    }
                }
                for (i = endColumnControls; i < printedTable.Columns.Count; i++)
                {
                    String headtext = printedTable.Columns[i].ColumnName.Trim();
                    if (pindex == 0)
                    {
                        int colwidth = Convert.ToInt16(ev.Graphics.MeasureString(headtext, prtTextFont).Width);
                        if (colwidth > width[i])
                        {
                            width[i] = colwidth;
                        }
                    }
                    if (x + width[i] > pheight)
                    {
                        break;
                    }
                    ev.Graphics.DrawString(headtext, prtTextFont, Brushes.Black, x, y + rowOfUpDistance);
                    x += width[i];
                }
                startColumnControls = endColumnControls;
                if (i < printedTable.Columns.Count)
                {
                    endColumnControls = i;
                    ev.HasMorePages = true;
                }
                else
                {   
                    endColumnControls = printedTable.Columns.Count;
                }
                ev.Graphics.DrawLine(pen, left, rowOfTop, x, rowOfTop);
                y += rowOfUpDistance + prtTextFont.Height + rowOfDownDistance;
                ev.Graphics.DrawLine(pen, left, y, x, y);
                for (i = curdgi; i < printedTable.Rows.Count; i++)
                {
                    x = left;
                    for (Int32 j = startColumnControls; j < endColumnControls; j++)
                    {
                        ev.Graphics.DrawString(printedTable.Rows[i][j].ToString().Trim(), prtTextFont, Brushes.Black, x, y + rowOfUpDistance);
                        x += width[j];
                    }
                    y += rowOfUpDistance + prtTextFont.Height + rowOfDownDistance;
                    ev.Graphics.DrawLine(pen, left, y, x, y);
                    if (y > pWidth - prtTextFont.Height - 30)
                    {
                        break;
                    }
                }
                ev.Graphics.DrawLine(pen, left, rowOfTop, left, y);
                x = left;
                for (Int32 k = startColumnControls; k < endColumnControls; k++)
                {
                    x += width[k];
                    ev.Graphics.DrawLine(pen, x, rowOfTop, x, y);
                }
                if (y > pWidth - prtTextFont.Height - 30)
                {
                    pindex++;
                    if (0 != startColumnControls)
                    {
                        curdgi = i + 1;
                    }
                    if (!ev.HasMorePages)
                    {
                        endColumnControls = 0;
                    }
                    ev.HasMorePages = true;
                }
            }
            public void PrintPreviewDataTable(DataTable prtTable)
            {
                PrintDocument prtDocument = new PrintDocument();
                try
                {
                    if (printName != String.Empty)
                    {
                        prtDocument.PrinterSettings.PrinterName = printName;
    
                    }
                    prtDocument.DefaultPageSettings.Landscape = true;
                    prtDocument.OriginAtMargins = false;
                    printedTable = prtTable;
                    pindex = 0;
                    curdgi = 0;
                    width = new int[printedTable.Columns.Count];
                    pheight = prtDocument.PrinterSettings.DefaultPageSettings.Bounds.Bottom;
                    pWidth = prtDocument.PrinterSettings.DefaultPageSettings.Bounds.Right;
                    prtDocument.PrintPage += new PrintPageEventHandler(Document_PrintPage);
                    PrintPreviewDialog prtPreviewDialog = new PrintPreviewDialog();
                    prtPreviewDialog.Document = prtDocument;
                    prtPreviewDialog.ShowIcon = false;
                    prtPreviewDialog.WindowState = FormWindowState.Maximized;
                    prtPreviewDialog.ShowDialog();
    
                }
                catch (InvalidPrinterException ex)
                {
                    MessageBox.Show("没有安装打印机");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("打印预览失败");
                }
    
            }
        }

    综合资料来源

    http://msdn.microsoft.com/zh-cn/library/system.drawing.printing.printdocument(v=VS.80).aspx

    http://blog.csdn.net/lee576/article/details/3352335

    http://s.yanghao.org/program/viewdetail.php?i=273227 打印预览正常,打印缺少大部分

    http://bbs.csdn.net/topics/340132124

  • 相关阅读:
    c# partial 关键字的使用
    动软代码生成器基础使用
    T-SQL :编程理论 (一)
    T-SQL :SQL Server系统数据库(二)
    T-SQL :SQL Server 定义数据完整性 6大约束(三)
    T-SQL:SQL语句处理顺序的坑(四)
    c#实战开发:以太坊私链搭建(一)
    T-SQL :TOP和OFFSET-FETCH筛选 (五)
    T-SQL:谓词和运算符(六)
    T-SQL:是NULL不是NULL(七)
  • 原文地址:https://www.cnblogs.com/IT-Bear/p/3229407.html
Copyright © 2011-2022 走看看