打印
打印帮助类
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; } } }
调用案例
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; }