所谓的潇洒

导航

打印

打印帮助类

using System;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;

namespace MyWinformProject
{
    public class PrintHelper
    {
        private const int HeadHeight = 40;//表头高度
        private readonly Font _titleFont = new Font("Verdana", 20, FontStyle.Bold);//标题字体
        private readonly Font _subTitleFont = new Font("Verdana", 12, FontStyle.Regular);//子标题字体
        private static readonly Font TableFont = new Font("Verdana", 10, FontStyle.Regular);//表内容字体
        private readonly SolidBrush _drawBrush = new SolidBrush(Color.Black);
        private readonly int _yUnit = TableFont.Height * 2;//单元格高度
        public int TotalNum = 0;
        //以下为模块内部使用
        private DataRow _dataRow;
        private DataTable _dataTable;
        private Control _control;
        private int _firstPrintRecordNumber;
        private string _headText = string.Empty;
        private int _pBottom;
        private int _pHeigh;
        //当前要所要打印的记录行数,由计算得到
        private int _pageLeft;
        private int _pageTop;
        private int _pWidth;
        private int _pageRecordNumber;
        private int _printRecordComplete;
        //打印相关对话框
        private PrintDocument _printDocument;
        private PageSetupDialog _pageSetupDialog;
        private PrintDialog _printDialog;
        private PrintPreviewDialog _printPreviewDlg;        
        //每页打印的记录条数
        private int _printRecordNumber;
        private int _printingPageNumber = 1;
        //第一页打印的记录条数
        //与列名无关的统计数据行的类目数(如,总计,小计......)
        private int _totalPage;
        private int[] _xUnit;
        //打印控件时控件截图
        Bitmap controlImage = null;

        private static object locker = new object();
        private static PrintHelper printHelper;

        private PrintHelper()
        {
            _printDocument = new PrintDocument();
            _pageSetupDialog = new PageSetupDialog();
            _pageSetupDialog.Document = _printDocument;
            _printDialog = new PrintDialog();
            _printDialog.Document = _printDocument;
            _printPreviewDlg = new PrintPreviewDialog();
            _printPreviewDlg.Document = _printDocument;
        }

        public static PrintHelper Instance
        {
            get
            {
                if (printHelper == null)
                {
                    lock (locker)
                    {
                        if (printHelper == null) printHelper = new PrintHelper();
                    }
                }
                return printHelper;
            }
        }

        /// <summary>
        /// 打印
        /// </summary>
        /// <param name="dt">要打印的DataTable</param>
        /// <param name="title">打印文件的标题</param>
        public void Print()
        {
            if (_printDialog.ShowDialog() == DialogResult.OK) _printDocument.Print();
        }

        /// <summary>
        /// 打印预览
        /// </summary>
        /// <param name="dt">要打印的DataTable</param>
        /// <param name="title">打印文件的标题</param>
        public void PrintPriview()
        {
            _printPreviewDlg.ShowDialog();
        }

        /// <summary>
        /// 页面设置
        /// </summary>
        /// <param name="isPrintCtrl">是否打印控件</param>
        public void PrintSetting(bool isPrintCtrl = false)
        {
            _pageSetupDialog.ShowDialog();
            if (isPrintCtrl) InitPrintDocument(_control, _headText);
            else InitPrintDocument(_dataTable, _headText);
        }

        /// <summary>
        /// 初始化打印文件
        /// </summary>
        /// <param name="dt">数据</param>
        /// <param name="title">标题:主标题|副标题1|副标题2...</param>
        /// <returns>错误信息,string.Empty:成功</returns>
        public string InitPrintDocument(DataTable dt, string title)
        {
            try
            {
                _dataTable = dt;
                _headText = title;
                _printDocument.DefaultPageSettings = _pageSetupDialog.PageSettings;
                _pageTop = _printDocument.DefaultPageSettings.Margins.Top;
                _pBottom = _printDocument.DefaultPageSettings.Margins.Bottom;
                _pWidth = _printDocument.DefaultPageSettings.Bounds.Width;
                _pHeigh = _printDocument.DefaultPageSettings.Bounds.Height;
                if (_dataTable != null)
                {
                    _xUnit = new int[_dataTable.Columns.Count];
                    _printRecordNumber = Convert.ToInt32((_pHeigh - _pageTop - _pBottom - _yUnit) / _yUnit);
                    _firstPrintRecordNumber = Convert.ToInt32((_pHeigh - _pageTop - _pBottom - HeadHeight - _yUnit) / _yUnit);

                    if (_dataTable.Rows.Count > _printRecordNumber)
                    {
                        if ((_dataTable.Rows.Count - _firstPrintRecordNumber) % _printRecordNumber == 0)
                        {
                            _totalPage = (_dataTable.Rows.Count - _firstPrintRecordNumber) / _printRecordNumber + 1;
                        }
                        else
                        {
                            _totalPage = (_dataTable.Rows.Count - _firstPrintRecordNumber) / _printRecordNumber + 2;
                        }
                    }
                    else
                    {
                        _totalPage = 1;
                    }
                }
                _printDocument.PrintPage += PrintDocumentPrintPage;
                _printDocument.DocumentName = _headText;
                return string.Empty;
            }
            catch(Exception ex)
            {
                return ex.Message;
            }
        }

        public string InitPrintDocument(Control ctl, string title)
        {
            try
            {
                _control = ctl;
                _headText = title;
                _printDocument.DefaultPageSettings = _pageSetupDialog.PageSettings;
                _pageTop = _printDocument.DefaultPageSettings.Margins.Top;
                _pBottom = _printDocument.DefaultPageSettings.Margins.Bottom;
                _pWidth = _printDocument.DefaultPageSettings.Bounds.Width;
                _pHeigh = _printDocument.DefaultPageSettings.Bounds.Height;
                _printDocument.PrintPage += PrintControl;
                _printDocument.DocumentName = _headText;
                if (ctl != null)
                {                    
                    Graphics mygraphics = ctl.CreateGraphics();
                    controlImage = new Bitmap(ctl.Width, ctl.Height, mygraphics);
                    Graphics memoryGraphics = Graphics.FromImage(controlImage);
                    Point p = new Point(0, 0);
                    p = ctl.PointToScreen(p);
                    memoryGraphics.CopyFromScreen(p.X, p.Y, 0, 0, ctl.Size);
                }
                return string.Empty;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        /// <summary>
        /// 打印当前页
        /// </summary>
        private void PrintDocumentPrintPage(object sende, PrintPageEventArgs e)
        {
            try
            {
                int tableWith = 0;
                string columnText;
                var format = new StringFormat { Alignment = StringAlignment.Center };
                var pen = new Pen(Brushes.Black, 1);//打印表格线格式

                #region 设置列宽

                foreach (DataRow dr in _dataTable.Rows)
                {
                    for (int i = 0; i < _dataTable.Columns.Count; i++)
                    {
                        int colwidth = Convert.ToInt32(e.Graphics.MeasureString(dr[i].ToString().Trim(), TableFont).Width);
                        if (colwidth > _xUnit[i])
                        {
                            _xUnit[i] = colwidth;
                        }
                    }
                }

                if (_printingPageNumber == 1)
                {
                    for (int cols = 0; cols <= _dataTable.Columns.Count - 1; cols++)
                    {
                        columnText = _dataTable.Columns[cols].ColumnName.Trim();
                        int colwidth = Convert.ToInt32(e.Graphics.MeasureString(columnText, TableFont).Width);
                        if (colwidth > _xUnit[cols])
                        {
                            _xUnit[cols] = colwidth;
                        }
                    }
                }
                for (int i = 0; i < _xUnit.Length; i++)
                {
                    tableWith += _xUnit[i];
                }

                #endregion

                _pageLeft = (e.PageBounds.Width - tableWith) / 2;
                int x = _pageLeft;
                int y = _pageTop;
                int stringY = _pageTop + (_yUnit - TableFont.Height) / 2;
                int rowOfTop = _pageTop;

                //第一页
                if (_printingPageNumber == 1)
                {
                    int subtitleHeight = PintTitle(e);
                    //设置为第一页时行数
                    if (_dataTable.Rows.Count < _firstPrintRecordNumber) _pageRecordNumber = _dataTable.Rows.Count;
                    else _pageRecordNumber = _firstPrintRecordNumber;

                    y = (_pageTop + _titleFont.Height + subtitleHeight + 10);
                    rowOfTop = y;
                    stringY = _pageTop + _titleFont.Height + subtitleHeight + 10 + (_yUnit - TableFont.Height) / 2;
                }
                else
                {
                    //计算剩下要打印的记录数
                    if (_dataTable.Rows.Count - _printRecordComplete >= _printRecordNumber) _pageRecordNumber = _printRecordNumber;
                    else _pageRecordNumber = _dataTable.Rows.Count - _printRecordComplete;
                }

                #region 列名

                if (_printingPageNumber == 1 || _pageRecordNumber > TotalNum) //最后一页只打印统计行时不打印列名
                {
                    //得到datatable的所有列名
                    for (int cols = 0; cols <= _dataTable.Columns.Count - 1; cols++)
                    {
                        columnText = _dataTable.Columns[cols].ColumnName.Trim();
                        e.Graphics.DrawString(columnText, TableFont, _drawBrush, x, stringY);
                        x += _xUnit[cols];
                    }
                }

                #endregion

                e.Graphics.DrawLine(pen, _pageLeft, rowOfTop, x, rowOfTop);
                stringY += _yUnit;
                y += _yUnit;
                e.Graphics.DrawLine(pen, _pageLeft, y, x, y);

                //当前页面已经打印的记录行数
                int printingLine = 0;
                while (printingLine < _pageRecordNumber)
                {
                    x = _pageLeft;
                    //确定要当前要打印的记录的行号
                    _dataRow = _dataTable.Rows[_printRecordComplete];
                    for (int cols = 0; cols <= _dataTable.Columns.Count - 1; cols++)
                    {
                        e.Graphics.DrawString(_dataRow[cols].ToString().Trim(), TableFont, _drawBrush, x, stringY);
                        x += _xUnit[cols];
                    }
                    stringY += _yUnit;
                    y += _yUnit;
                    e.Graphics.DrawLine(pen, _pageLeft, y, x, y);

                    printingLine += 1;
                    _printRecordComplete += 1;
                    if (_printRecordComplete >= _dataTable.Rows.Count)
                    {
                        e.HasMorePages = false;
                        _printRecordComplete = 0;
                    }
                }

                e.Graphics.DrawLine(pen, _pageLeft, rowOfTop, _pageLeft, y);
                x = _pageLeft;
                for (int cols = 0; cols < _dataTable.Columns.Count; cols++)
                {
                    x += _xUnit[cols];
                    e.Graphics.DrawLine(pen, x, rowOfTop, x, y);
                }

                _printingPageNumber += 1;

                if (_printingPageNumber > _totalPage)
                {
                    e.HasMorePages = false;
                    _printingPageNumber = 1;
                    _printRecordComplete = 0;
                }
                else
                {
                    e.HasMorePages = true;
                }
            }
            catch(Exception ex)
            {
                //LogHelper.logger.Error(ex);
            }
        }

        /// <summary>
        /// 打印当前页
        /// </summary>
        private void PrintControl(object sende, PrintPageEventArgs e)
        {
            try
            {
                int subtitleHeight = PintTitle(e);
                //打印控件截图
                int y = _pageTop + _titleFont.Height + subtitleHeight + 10;
                e.Graphics.DrawImage(controlImage, 0, y);
            }
            catch (Exception ex)
            {
                //LogHelper.logger.Error(ex);
            }
        }

        private int PintTitle(PrintPageEventArgs e)
        {
            var format = new StringFormat { Alignment = StringAlignment.Center };
            //打印标题
            var arr = _headText.Split(new[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
            if (arr.Length > 0) e.Graphics.DrawString(arr[0], _titleFont, _drawBrush, new Point(e.PageBounds.Width / 2, _pageTop), format);
            //副标题
            var subtitleHeight = 0;
            for (int i = 1; i < arr.Length; i++)
            {
                e.Graphics.DrawString(arr[i], _subTitleFont, _drawBrush, new Point(e.PageBounds.Width / 2, subtitleHeight + _pageTop + _titleFont.Height), format);
                subtitleHeight += _subTitleFont.Height;
            }
            return subtitleHeight;
        }
    }
}
View Code

调用案例

bool hasInitDocument = false;        
        private void btn_PrintPreview_Click(object sender, EventArgs e)
        {
            try
            {
                if (!hasInitDocument)
                {
                    if (!InitDocument()) return;
                    hasInitDocument = true;
                }
                PrintHelper.Instance.PrintPriview();
            }
            catch(Exception ex)
            {
                LogHelper.logger.Error(ex);
            }
        }

        private void btn_Print_Click(object sender, EventArgs e)
        {
            try
            {
                if (!hasInitDocument)
                {
                    if (!InitDocument()) return;
                    hasInitDocument = true;
                }
                PrintHelper.Instance.Print();
            }
            catch (Exception ex)
            {
                LogHelper.logger.Error(ex);
            }
        }

        private bool InitDocument()
        {
            DataTable table = GetAllData();
            if (table == null) return false;
            PrintHelper.Instance.InitPrintDocument(table, "记录");
            return true;
        }

        private void btn_PrintPageSet_Click(object sender, EventArgs e)
        {
            PrintHelper.Instance.PrintSetting();
            hasInitDocument = false;
        }    
View Code

 

posted on 2020-12-13 15:43  所谓的潇洒  阅读(131)  评论(0编辑  收藏  举报