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.效果: