PrintDataGridDoc.cs
上传用户:fgkjxx
上传日期:2009-12-18
资源大小:3k
文件大小:11k
源码类别:

打印编程

开发平台:

C#

  1. using System;
  2. using System.IO;
  3. using System.Drawing;
  4. using System.Runtime.InteropServices;
  5. using System.Drawing.Printing;
  6. using System.Data;
  7. using System.Windows.Forms;
  8. namespace PrintDataGrid 
  9. {
  10. public class MyPrintDoc : PrintDocument 
  11. {
  12.      
  13. private DataGrid _dataGrid;
  14. private int _currentPage = 0;
  15. private int _currentRow = 0;
  16. private int _rowCount = 0;
  17. private int _colCount = 0;
  18. private int _linesPerPage = 0;
  19. private RectangleF _headerR;
  20. private RectangleF _bodyR;
  21. private RectangleF _footerR;
  22. private string _headerText = "This is a test";
  23. // these will be created in BeginPrint and 
  24. // destroyed in EndPrint.
  25. private Font _headerFont;
  26. private Font _bodyFont;
  27. private float _headerHeight = 0;
  28. private float _bodyFontHeight = 0;
  29. private float _footerHeight = 0;
  30. private Brush _defaultBrush = Brushes.Black;
  31. private Pen _defaultPen = new Pen(Brushes.Black, .25f);
  32. public string HeaderText 
  33. get { return _headerText;} 
  34. set { _headerText = value; }
  35. }
  36. public MyPrintDoc(DataGrid dataGrid) : base() 
  37. {
  38. _dataGrid = dataGrid;
  39. _rowCount = ((DataSet)(dataGrid.DataSource)).Tables[0].Rows.Count;
  40. _colCount = dataGrid.TableStyles[0].GridColumnStyles.Count;
  41. }
  42. protected override void OnBeginPrint(PrintEventArgs ev) 
  43. {
  44. base.OnBeginPrint(ev) ;
  45. // make sure we reset this before printing
  46. _currentPage = 0;
  47. _currentRow = 0;
  48. _headerFont = new Font("Arial", 24, GraphicsUnit.World);
  49. _bodyFont = new Font("Arial", 16, GraphicsUnit.World);
  50. }
  51. protected override void OnEndPrint(PrintEventArgs ev) 
  52. {
  53. base.OnEndPrint(ev);
  54. _headerFont.Dispose();
  55. _bodyFont.Dispose();
  56. }
  57. protected override void OnQueryPageSettings(QueryPageSettingsEventArgs ev) 
  58. {
  59. base.OnQueryPageSettings(ev);
  60. }
  61. protected int DrawDataGridRow(Graphics g, int currentLine)
  62. {
  63. float y = getCurrentY(currentLine, _bodyR.Top, _bodyFontHeight);
  64. float x = _bodyR.Left;
  65. int colGap = 5;
  66. string cellValue;
  67. RectangleF cellR = new RectangleF(x, y, _bodyR.Right, y);
  68. StringFormat drawFormat = new StringFormat();
  69. drawFormat.Alignment = StringAlignment.Center;
  70. for(int j = 0; j < _colCount; j++)
  71. {
  72. if(_dataGrid.TableStyles[0].GridColumnStyles[j].Width > 0)
  73. {
  74. cellValue = _dataGrid[_currentRow, j].ToString(); 
  75. cellR.X = x;
  76. cellR.Y = y;
  77. cellR.Width = _dataGrid.TableStyles[0].GridColumnStyles[j].Width;
  78. cellR.Height = _bodyFontHeight;
  79. g.DrawString(cellValue, _bodyFont, _defaultBrush, cellR, drawFormat);
  80. x += _dataGrid.TableStyles[0].GridColumnStyles[j].Width + colGap;
  81. }
  82. return 0;
  83. }
  84. protected int DrawDataGridHeader(Graphics g)
  85. {
  86. string cellValue;
  87. float y = getCurrentY(2, _bodyR.Top, _bodyFontHeight);
  88. float x = _bodyR.Left;
  89. RectangleF cellR = new RectangleF(x, y, _bodyR.Right, y);
  90. StringFormat drawFormat = new StringFormat();
  91. drawFormat.Alignment = StringAlignment.Center;
  92. for(int j = 0; j < _colCount; j++)
  93. {
  94. if(_dataGrid.TableStyles[0].GridColumnStyles[j].Width > 0)
  95. {
  96. cellValue = _dataGrid.TableStyles[0].GridColumnStyles[j].HeaderText; 
  97. cellR.X = x;
  98. cellR.Y = y;
  99. cellR.Width = _dataGrid.TableStyles[0].GridColumnStyles[j].Width;
  100. cellR.Height = _bodyFontHeight;
  101. g.DrawString(cellValue, _bodyFont, _defaultBrush, cellR, drawFormat);
  102. x += _dataGrid.TableStyles[0].GridColumnStyles[j].Width + 5; 
  103. }
  104. y = getCurrentY(3, _bodyR.Top, _bodyFontHeight) + _bodyFontHeight / 2;
  105. g.DrawLine(_defaultPen, _bodyR.Left, y, cellR.Right, y);
  106. return 0;
  107. }
  108. protected override void OnPrintPage(PrintPageEventArgs ev) 
  109. {
  110. base.OnPrintPage(ev);
  111. if ( _currentPage == 0 )
  112. {
  113. marginInfo mi;
  114. float leftMargin = 0f;
  115. float rightMargin = 0f;
  116. float topMargin = 0f;
  117. float bottomMargin = 0f;
  118. float pageHeight = 0f;
  119. float pageWidth = 0f;
  120. // retrieve the hard printer margins
  121. IntPtr hDc = ev.Graphics.GetHdc();
  122. try 
  123. {
  124. mi = new marginInfo(hDc.ToInt32());    
  125. finally 
  126. {
  127. ev.Graphics.ReleaseHdc(hDc);
  128. }
  129.             
  130. ev.Graphics.PageUnit = GraphicsUnit.Inch;
  131. ev.Graphics.PageScale = .01f;
  132. ev.Graphics.TranslateTransform(-mi.Left, -mi.Top);
  133. // retrieve the margins
  134. leftMargin = ev.MarginBounds.Left - mi.Left;
  135. rightMargin = ev.MarginBounds.Right;
  136. topMargin = ev.MarginBounds.Top - mi.Top;
  137. bottomMargin = ev.MarginBounds.Bottom;
  138. pageHeight = bottomMargin - topMargin;
  139. pageWidth = rightMargin - leftMargin;
  140. // used to define the sections of the document
  141. _headerHeight = _headerFont.GetHeight(ev.Graphics);
  142. _footerHeight = _bodyFont.GetHeight(ev.Graphics);            
  143. // report header
  144. _headerR = new RectangleF(leftMargin, topMargin, pageWidth, _headerHeight);
  145. // report body
  146. _bodyR = new RectangleF(leftMargin, _headerR.Bottom, pageWidth, pageHeight - _headerR.Height - _footerHeight);
  147. // report footer
  148. _footerR = new RectangleF(leftMargin, _bodyR.Bottom, pageWidth, _footerHeight * 2);
  149. // how many lines can we fit on a page?              
  150. _bodyFontHeight = _footerHeight;
  151. _linesPerPage = Convert.ToInt32(_bodyR.Height / _bodyFontHeight) - 1;
  152. }
  153. _currentPage++;
  154.             
  155. // uncomment these lines to draw borders around the rectangles
  156. /*
  157.  drawRect(ev.Graphics, _defaultPen, leftMargin, topMargin, pageWidth, headerHeight);
  158.  drawRect(ev.Graphics, _defaultPen, leftMargin, ReportheaderR.Bottom, pageWidth, pageHeight - ReportheaderR.Height - footerHeight);
  159.  drawRect(ev.Graphics, _defaultPen, leftMargin, bodyR.Bottom, pageWidth, ReportfooterR.Height);                                    
  160.             
  161.  centerText(ev.Graphics, "Header section", _headerFont, _defaultBrush, ReportheaderR);
  162.  centerText(ev.Graphics, "Body section", _headerFont, _defaultBrush, bodyR);
  163.  centerText(ev.Graphics, "Footer section", _headerFont, _defaultBrush, ReportfooterR);           
  164.   return;
  165.  */
  166. // print the header once per page
  167. centerText(ev.Graphics, _headerText, _headerFont, _defaultBrush, _headerR);
  168. DrawDataGridHeader(ev.Graphics);
  169. // the header = 4 lines
  170. int currentLine = 4;
  171. while(currentLine + 1 < _linesPerPage && _currentRow < _rowCount )
  172. {
  173. DrawDataGridRow(ev.Graphics, currentLine);
  174. currentLine ++;
  175. _currentRow ++;
  176. }
  177. // page number
  178. centerText(ev.Graphics, "Page " + _currentPage.ToString(), _bodyFont, _defaultBrush, _footerR);
  179. // Do we have more pages to print?
  180. if (_currentRow != _rowCount) 
  181. {
  182. ev.HasMorePages = true;
  183. else 
  184. {
  185. ev.HasMorePages = false;
  186. }
  187. private float getCurrentY(int currentLine, float topMargin, float fontHeight) 
  188. {
  189. return topMargin + (currentLine * fontHeight);
  190. }
  191. // my wrapper for DrawRectangle
  192. private void drawRect(Graphics g, Pen p, float left, float top, float width, float height) 
  193. {
  194. g.DrawRectangle(_defaultPen, left, top, width, height);
  195. }
  196. // the StringFormat class has a lot of cool features
  197. private void centerText(Graphics g, string t, Font f, Brush b, RectangleF rect) 
  198. {
  199. StringFormat sf = new StringFormat();
  200. // center horizontally
  201. sf.Alignment = StringAlignment.Center;
  202. // center vertically
  203. sf.LineAlignment = StringAlignment.Center;
  204. g.DrawString(t, f, b, rect, sf);
  205. }
  206. // used for debugging
  207. private void dumpRectF(RectangleF rect) 
  208. {
  209. System.Diagnostics.Debug.WriteLine(rect.ToString());
  210. }
  211. public void PrintDataGrid()
  212. {
  213. PrintPreviewDialog previewDialog = new PrintPreviewDialog();    
  214. /*
  215. // display a pagesetup dialog
  216. PageSetupDialog pageSetup = new PageSetupDialog();
  217. pageSetup.Document = mydoc;
  218. pageSetup.MinMargins.Left = 20;
  219. pageSetup.MinMargins.Top = 20;
  220. pageSetup.MinMargins.Bottom = 20;
  221. DialogResult Rc = pageSetup.ShowDialog();
  222. if (Rc == DialogResult.Cancel) 
  223. {
  224. return;
  225. }            
  226. */
  227. // display the preview dialog
  228. previewDialog.Document = this;
  229. previewDialog.PrintPreviewControl.Zoom = 1.0;
  230. previewDialog.WindowState = FormWindowState.Maximized;
  231. previewDialog.ShowInTaskbar = true;
  232. previewDialog.ShowDialog();
  233. }
  234. }
  235. public class marginInfo 
  236. {
  237. [DllImport("gdi32.dll")]
  238. private static extern Int16 GetDeviceCaps([In] [MarshalAs (UnmanagedType.U4)] int hDc, [In] [MarshalAs (UnmanagedType.U2)] Int16 funct);
  239. private float _leftMargin = 0;
  240. private float _topMargin = 0;
  241. private float _rightMargin = 0;
  242. private float _bottomMargin = 0;
  243. const short HORZSIZE      = 4;     /* Horizontal size in millimeters */
  244. const short VERTSIZE      = 6;     /* Vertical size in millimeters */
  245. const short HORZRES       = 8;     /* Horizontal width in pixels */
  246. const short VERTRES       = 10;    /* Vertical height in pixels*/
  247. const short PHYSICALOFFSETX = 112; /* Physical Printable Area x margin */
  248. const short PHYSICALOFFSETY = 113; /* Physical Printable Area y margin */
  249. // Modified from code originally written by Ron Allen (Ron@us-src.com).
  250. public marginInfo(int deviceHandle) 
  251. {
  252. // Non printable margin in pixels
  253. float offsetX = Convert.ToSingle(GetDeviceCaps(deviceHandle, PHYSICALOFFSETX));
  254. float offsetY = Convert.ToSingle(GetDeviceCaps(deviceHandle, PHYSICALOFFSETY));
  255. // printable page size in pixels
  256. float resolutionX = Convert.ToSingle(GetDeviceCaps(deviceHandle, HORZRES));
  257. float resolutionY = Convert.ToSingle(GetDeviceCaps(deviceHandle, VERTRES));
  258. // printable page size in current unit (in this case, converted to inches)
  259. float horizontalSize = Convert.ToSingle(GetDeviceCaps(deviceHandle, HORZSIZE))/25.4f;
  260. float verticalSize = Convert.ToSingle(GetDeviceCaps(deviceHandle, VERTSIZE))/25.4f;
  261. float pixelsPerInchX = resolutionX/horizontalSize;
  262. float pixelsPerInchY = resolutionY/verticalSize;
  263. _leftMargin  = (offsetX/pixelsPerInchX)* 100.0f;
  264. _topMargin   = (offsetY/pixelsPerInchX) * 100.0f;
  265. _bottomMargin  = _topMargin + (verticalSize * 100.0f);
  266. _rightMargin  = _leftMargin + (horizontalSize * 100.0f);
  267. }
  268. public float Left 
  269. {
  270. get 
  271. {
  272. return _leftMargin;
  273. }
  274. }
  275. public float Right 
  276. {
  277. get 
  278. {
  279. return _rightMargin;
  280. }
  281. }
  282. public float Top 
  283. {
  284. get 
  285. {
  286. return _topMargin;
  287. }
  288. }
  289. public float Bottom 
  290. {
  291. get 
  292. {
  293. return _bottomMargin;
  294. }
  295. }
  296. public override string ToString() 
  297. {
  298. return "left=" + _leftMargin.ToString() + ", top=" + _topMargin.ToString() + ", right=" + _rightMargin.ToString() + ", bottom=" + _bottomMargin.ToString();
  299. }
  300. }
  301. }