C# PrintDocument 打印表格

1.封装好的辅助类:

  1 using System;
  2 using System.Data;
  3 using System.Drawing;
  4 using System.Drawing.Printing;
  5 using System.Windows.Forms;
  6 
  7 namespace RC.Finance
  8 {
  9     /// <summary>
 10     ///     打印,打印预览 
 11     /// </summary>
 12     public class PrintHelper
 13     {
 14         //以下用户可自定义
 15         //当前要打印文本的字体及字号
 16         private const int HeadHeight = 40;
 17         private static readonly Font TableFont = new Font("Verdana", 10, FontStyle.Regular);
 18         private readonly SolidBrush _drawBrush = new SolidBrush(Color.Black);
 19         //表头字体
 20         private readonly Font _headFont = new Font("Verdana", 20, FontStyle.Bold);
 21         //表头文字
 22         private readonly int _yUnit = TableFont.Height * 2;
 23         public int TotalNum = 0;
 24         //以下为模块内部使用
 25         private DataRow _dataRow;
 26         private DataTable _dataTable;
 27         private int _firstPrintRecordNumber;
 28         private string _headText = string.Empty;
 29         private int _pBottom;
 30         private int _pHeigh;
 31         //当前要所要打印的记录行数,由计算得到
 32         private int _pageLeft;
 33         private int _pRight;
 34         private int _pageTop;
 35         private int _pWidth;
 36         private int _pageRecordNumber;
 37         private PrintDocument _printDocument;
 38         private PageSetupDialog _pageSetupDialog;
 39         private int _printRecordComplete;
 40         //每页打印的记录条数
 41         private int _printRecordNumber;
 42         private int _printingPageNumber = 1;
 43         //第一页打印的记录条数
 44         //与列名无关的统计数据行的类目数(如,总计,小计......)
 45         private int _totalPage;
 46         private int[] _xUnit;
 47 
 48         /// <summary>
 49         ///     打印
 50         /// </summary>
 51         /// <param name="dt">要打印的DataTable</param>
 52         /// <param name="title">打印文件的标题</param>
 53         public void Print(DataTable dt, string title)
 54         {
 55             try
 56             {
 57                 CreatePrintDocument(dt, title).Print();
 58             }
 59             catch (Exception ex)
 60             {
 61                 MessageBox.Show("打印错误,请检查打印设置!");
 62             }
 63         }
 64 
 65         /// <summary>
 66         ///     打印预览
 67         /// </summary>
 68         /// <param name="dt">要打印的DataTable</param>
 69         /// <param name="title">打印文件的标题</param>
 70         public void PrintPriview(DataTable dt, string title)
 71         {
 72             try
 73             {
 74                 var printPriview = new PrintPreviewDialog
 75                     {
 76                         Document = CreatePrintDocument(dt, title),
 77                         WindowState = FormWindowState.Maximized
 78                     };
 79                 printPriview.ShowDialog();
 80             }
 81             catch (Exception ex)
 82             {
 83                 MessageBox.Show("打印错误,请检查打印设置!");
 84             }
 85         }
 86         public void PrintSetting()
 87         {
 88             try
 89             {
 90                 _pageSetupDialog.ShowDialog();
 91             }
 92             catch (Exception ex)
 93             {
 94                 MessageBox.Show("打印错误,请检查打印设置!");
 95             }
 96         }
 97         /// <summary>
 98         ///     创建打印文件
 99         /// </summary>
100         private PrintDocument CreatePrintDocument(DataTable dt, string title)
101         {
102             _dataTable = dt;
103             _headText = title;
104 
105             var pageSetup = new PageSetupDialog();
106 
107             _printDocument = new PrintDocument { DefaultPageSettings = pageSetup.PageSettings };
108             _printDocument.DefaultPageSettings.Landscape = true; //设置打印横向还是纵向
109             //PLeft = 30; //DataTablePrinter.DefaultPageSettings.Margins.Left;
110             _pageTop = _printDocument.DefaultPageSettings.Margins.Top;
111             //PRight = DataTablePrinter.DefaultPageSettings.Margins.Right;
112             _pBottom = _printDocument.DefaultPageSettings.Margins.Bottom;
113             _pWidth = _printDocument.DefaultPageSettings.Bounds.Width;
114             _pHeigh = _printDocument.DefaultPageSettings.Bounds.Height;
115             _xUnit = new int[_dataTable.Columns.Count];
116             _printRecordNumber = Convert.ToInt32((_pHeigh - _pageTop - _pBottom - _yUnit) / _yUnit);
117             _firstPrintRecordNumber = Convert.ToInt32((_pHeigh - _pageTop - _pBottom - HeadHeight - _yUnit) / _yUnit);
118 
119             if (_dataTable.Rows.Count > _printRecordNumber)
120             {
121                 if ((_dataTable.Rows.Count - _firstPrintRecordNumber) % _printRecordNumber == 0)
122                 {
123                     _totalPage = (_dataTable.Rows.Count - _firstPrintRecordNumber) / _printRecordNumber + 1;
124                 }
125                 else
126                 {
127                     _totalPage = (_dataTable.Rows.Count - _firstPrintRecordNumber) / _printRecordNumber + 2;
128                 }
129             }
130             else
131             {
132                 _totalPage = 1;
133             }
134 
135             _printDocument.PrintPage += PrintDocumentPrintPage;
136             _printDocument.DocumentName = _headText;
137 
138             return _printDocument;
139         }
140 
141         /// <summary>
142         ///     打印当前页
143         /// </summary>
144         private void PrintDocumentPrintPage(object sende, PrintPageEventArgs @event)
145         {
146             int tableWith = 0;
147             string columnText;
148             var font = new StringFormat { Alignment = StringAlignment.Center };
149             var pen = new Pen(Brushes.Black, 1);//打印表格线格式
150 
151             #region 设置列宽
152 
153             foreach (DataRow dr in _dataTable.Rows)
154             {
155                 for (int i = 0; i < _dataTable.Columns.Count; i++)
156                 {
157                     int colwidth = Convert.ToInt32(@event.Graphics.MeasureString(dr[i].ToString().Trim(), TableFont).Width);
158                     if (colwidth > _xUnit[i])
159                     {
160                         _xUnit[i] = colwidth;
161                     }
162                 }
163             }
164 
165             if (_printingPageNumber == 1)
166             {
167                 for (int cols = 0; cols <= _dataTable.Columns.Count - 1; cols++)
168                 {
169                     columnText = _dataTable.Columns[cols].ColumnName.Trim();
170                     int colwidth = Convert.ToInt32(@event.Graphics.MeasureString(columnText, TableFont).Width);
171                     if (colwidth > _xUnit[cols])
172                     {
173                         _xUnit[cols] = colwidth;
174                     }
175                 }
176             }
177             for (int i = 0; i < _xUnit.Length; i++)
178             {
179                 tableWith += _xUnit[i];
180             }
181 
182             #endregion
183 
184             _pageLeft = (@event.PageBounds.Width - tableWith) / 2;
185             int x = _pageLeft;
186             int y = _pageTop;
187             int stringY = _pageTop + (_yUnit - TableFont.Height) / 2;
188             int rowOfTop = _pageTop;
189 
190             //第一页
191             if (_printingPageNumber == 1)
192             {
193                 //打印表头
194                 var arr = _headText.Split(new[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
195                 if (arr.Length > 1)
196                 {
197                     @event.Graphics.DrawString(arr[0],
198                         _headFont,
199                         _drawBrush,
200                         new Point(@event.PageBounds.Width / 2, _pageTop), font);
201                 }
202                 //副标题
203                 var subtitleHeight = 0;
204                 for (int i = 1; i < arr.Length; i++)
205                 {
206                     @event.Graphics.DrawString(arr[i],
207                         new Font("Verdana", 12, FontStyle.Regular),
208                         _drawBrush,
209                         new Point(@event.PageBounds.Width / 2, _pageTop + _headFont.Height),
210                         font);
211                     subtitleHeight += new Font("Verdana", 12, FontStyle.Regular).Height;
212                 }
213 
214                 //设置为第一页时行数 
215                 if (_dataTable.Rows.Count < _firstPrintRecordNumber)
216                 {
217                     _pageRecordNumber = _dataTable.Rows.Count;
218                 }
219                 else
220                 {
221                     _pageRecordNumber = _firstPrintRecordNumber;
222                 }
223 
224                 rowOfTop = y = (_pageTop + _headFont.Height + subtitleHeight + 10);
225                 stringY = _pageTop + _headFont.Height + subtitleHeight + 10 + (_yUnit - TableFont.Height) / 2;
226             }
227             else
228             {
229                 //计算,余下的记录条数是否还可以在一页打印,不满一页时为假
230                 if (_dataTable.Rows.Count - _printRecordComplete >= _printRecordNumber)
231                 {
232                     _pageRecordNumber = _printRecordNumber;
233                 }
234                 else
235                 {
236                     _pageRecordNumber = _dataTable.Rows.Count - _printRecordComplete;
237                 }
238             }
239 
240             #region 列名
241 
242             if (_printingPageNumber == 1 || _pageRecordNumber > TotalNum) //最后一页只打印统计行时不打印列名
243             {
244                 //得到datatable的所有列名
245                 for (int cols = 0; cols <= _dataTable.Columns.Count - 1; cols++)
246                 {
247                     columnText = _dataTable.Columns[cols].ColumnName.Trim();
248 
249                     int colwidth = Convert.ToInt32(@event.Graphics.MeasureString(columnText, TableFont).Width);
250                     @event.Graphics.DrawString(columnText, TableFont, _drawBrush, x, stringY);
251                     x += _xUnit[cols];
252                 }
253             }
254 
255             #endregion
256 
257             @event.Graphics.DrawLine(pen, _pageLeft, rowOfTop, x, rowOfTop);
258             stringY += _yUnit;
259             y += _yUnit;
260             @event.Graphics.DrawLine(pen, _pageLeft, y, x, y);
261 
262             //当前页面已经打印的记录行数
263             int printingLine = 0;
264             while (printingLine < _pageRecordNumber)
265             {
266                 x = _pageLeft;
267                 //确定要当前要打印的记录的行号
268                 _dataRow = _dataTable.Rows[_printRecordComplete];
269                 for (int cols = 0; cols <= _dataTable.Columns.Count - 1; cols++)
270                 {
271                     @event.Graphics.DrawString(_dataRow[cols].ToString().Trim(), TableFont, _drawBrush, x, stringY);
272                     x += _xUnit[cols];
273                 }
274                 stringY += _yUnit;
275                 y += _yUnit;
276                 @event.Graphics.DrawLine(pen, _pageLeft, y, x, y);
277 
278                 printingLine += 1;
279                 _printRecordComplete += 1;
280                 if (_printRecordComplete >= _dataTable.Rows.Count)
281                 {
282                     @event.HasMorePages = false;
283                     _printRecordComplete = 0;
284                 }
285             }
286 
287             @event.Graphics.DrawLine(pen, _pageLeft, rowOfTop, _pageLeft, y);
288             x = _pageLeft;
289             for (int cols = 0; cols < _dataTable.Columns.Count; cols++)
290             {
291                 x += _xUnit[cols];
292                 @event.Graphics.DrawLine(pen, x, rowOfTop, x, y);
293             }
294 
295 
296             _printingPageNumber += 1;
297 
298             if (_printingPageNumber > _totalPage)
299             {
300                 @event.HasMorePages = false;
301                 _printingPageNumber = 1;
302                 _printRecordComplete = 0;
303             }
304             else
305             {
306                 @event.HasMorePages = true;
307             }
308         }
309     }
310 }

2.调用方法:

打印:new PrintHelper().Print(dataTable,title);

预览:new PrintHelper().PrintPriview(dataTable,title);

3.效果:

 

posted @ 2018-04-13 01:40  softwyy  阅读(4882)  评论(0编辑  收藏  举报