C# 使用PrintDocument 绘制表格 完成 打印预览 DataTable

 

经过不断的Google与baidu,最终整理出来的打印类

主要是根据两个参考的类组合而成,稍微修改了一下,参考代码及来源见最后(其中一份是VB语言的)

其中遇到的一些问题也已经得到了解决(分页,打印预览点击打印内容缺失)

------------------------------------------------------------------------------

相关知识

PrintDocument

定义一个可再次使用的对象,该对象将输出发送到打印机。

命名空间:System.Drawing.Printing
程序集:System.Drawing(在 system.drawing.dll 中)

通常可以创建 PrintDocument 类的实例,设置描述打印方式的属性,然后调用 Print 方法开始打印进程。通过使用 PrintPageEventArgs 中包含的 Graphics 来处理用于指定打印输出的 PrintPage 事

PrintDocument.PrintPage 事件

当需要为当前页打印的输出时发生。

PrintDocument.Print 方法

开始文档的打印进程。

PrintPageEventArgs.HasMorePages 

获取或设置一个值,该值指示是否打印附加页。

打印类:

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

打印多页时 要根据剩余页数判断并设置 HasMorePages 是否继续执行 PrintPage

打印预览中点击打印按钮,实际上会再次执行 PrintPage 事件,所以再打印完文档后 应该对相关属性进行重置

  1. if (PrintingPageNumber > TotalPage)
  2. {
  3. Ev.HasMorePages = false;
  4. PrintingPageNumber = ;
  5. PrintRecordComplete = ;
  6. }
  7. else
  8. {
  9. Ev.HasMorePages = true;
  10. }

如何绘制表格1

  1. Imports System.Drawing
  2. Imports System.Drawing.Pen
  3. Imports System.Drawing.Font
  4. Imports System.Drawing.PointF
  5. Imports System.Drawing.Color
  6. Imports System.Drawing.Printing
  7. Imports System.Windows.Forms
  8. Imports System.Windows.Forms.DataGrid
  9.  
  10. Public Class PrintDataTable
  11. '以下用户可自定义
  12. '当前要打印文本的字体及字号
  13. Private TableFont As New Font("宋体", )
  14. '表头字体
  15. Private HeadFont As New Font("宋体", , FontStyle.Bold)
  16. '副表头字体
  17. Private SubHeadFont As New Font("宋体", , FontStyle.Regular)
  18. '表头文字
  19. Private HeadText As String
  20. '副表头左文字
  21. Private SubHeadLeftText As String
  22. '副表头右文字
  23. Private SubHeadRightText As String
  24. '表头高度
  25. Private HeadHeight As Integer =
  26. '副表头高度
  27. Private SubHeadHeight As Integer =
  28. '表脚字体
  29. Private FootFont As New Font("宋体", , FontStyle.Regular)
  30. '副表脚字体
  31. Private SubFootFont As New Font("宋体", , FontStyle.Regular)
  32. '表脚文字
  33. Private FootText As String
  34. '副表脚左文字
  35. Private SubFootLeftText As String
  36. '副表脚右文字
  37. Private SubFootRightText As String
  38. '表脚高度
  39. Private FootHeight As Integer =
  40. '副表脚高度
  41. Private SubFootHeight As Integer =
  42. '表的基本单位
  43. Dim XUnit As Integer
  44. Dim YUnit As Integer = TableFont.Height * 2.5
  45. '以下为模块内部使用
  46. Private Ev As PrintPageEventArgs
  47. Private DataTablePrinter As PrintDocument
  48. Private DataGridColumn As DataColumn
  49. Private DataGridRow As DataRow
  50. Private DataTablePrint As DataTable
  51. '当前要打印的行
  52. Private Rows As Integer
  53. '当前DATAGRID共有多少列
  54. Private ColsCount As Integer
  55. '当前正要打印的行号
  56. Private PrintingLineNumber As Integer
  57. '当前要所要打印的记录行数,由计算得到
  58. Private PageRecordNumber As Integer
  59. '正要打印的页号
  60. Private PrintingPageNumber As Integer
  61. '共需要打印的页数
  62. Private PageNumber As Integer
  63. '当前还有多少页没有打印
  64. Private PrintRecordLeave As Integer
  65. '已经打印完的记录数
  66. Private PrintRecordComplete As Integer
  67. Private PLeft As Integer
  68. Private PTop As Integer
  69. Private PRight As Integer
  70. Private PBottom As Integer
  71. Private PWidth As Integer
  72. Private PHeigh As Integer
  73. '当前画笔颜色
  74. Private DrawBrush As New SolidBrush(System.Drawing.Color.Black)
  75. '每页打印的记录条数
  76. Private PrintRecordNumber As Integer
  77. '总共应该打印的页数
  78. Private TotalPage As Integer
  79.  
  80. Sub New(ByVal TableSource As DataTable)
  81. DataTablePrint = New DataTable
  82. DataTablePrint = TableSource
  83. ColsCount = DataTablePrint.Columns.Count
  84. End Sub
  85.  
  86. '用户自定义字体及字号
  87. Public WriteOnly Property SetTableFont() As System.Drawing.Font
  88. Set(ByVal Value As System.Drawing.Font)
  89. TableFont = Value
  90. End Set
  91. End Property
  92.  
  93. Public WriteOnly Property SetHeadFont() As System.Drawing.Font
  94. Set(ByVal Value As System.Drawing.Font)
  95. HeadFont = Value
  96. End Set
  97. End Property
  98.  
  99. Public WriteOnly Property SetSubHeadFont() As System.Drawing.Font
  100. Set(ByVal Value As System.Drawing.Font)
  101. SubHeadFont = Value
  102. End Set
  103. End Property
  104.  
  105. Public WriteOnly Property SetFootFont() As System.Drawing.Font
  106. Set(ByVal Value As System.Drawing.Font)
  107. FootFont = Value
  108. End Set
  109. End Property
  110.  
  111. Public WriteOnly Property SetSubFootFont() As System.Drawing.Font
  112. Set(ByVal Value As System.Drawing.Font)
  113. SubFootFont = Value
  114. End Set
  115. End Property
  116.  
  117. Public WriteOnly Property SetHeadText() As String
  118. Set(ByVal Value As String)
  119. HeadText = Value
  120. End Set
  121. End Property
  122.  
  123. Public WriteOnly Property SetSubHeadLeftText() As String
  124. Set(ByVal Value As String)
  125. SubHeadLeftText = Value
  126. End Set
  127. End Property
  128.  
  129. Public WriteOnly Property SetSubHeadRightText() As String
  130. Set(ByVal Value As String)
  131. SubHeadRightText = Value
  132. End Set
  133. End Property
  134.  
  135. Public WriteOnly Property SetFootText() As String
  136. Set(ByVal Value As String)
  137. FootText = Value
  138. End Set
  139. End Property
  140.  
  141. Public WriteOnly Property SetSubFootLeftText() As String
  142. Set(ByVal Value As String)
  143. SubFootLeftText = Value
  144. End Set
  145. End Property
  146.  
  147. Public WriteOnly Property SetSubFootRightText() As String
  148. Set(ByVal Value As String)
  149. SubFootRightText = Value
  150. End Set
  151. End Property
  152.  
  153. Public WriteOnly Property SetHeadHeight() As Integer
  154. Set(ByVal Value As Integer)
  155. HeadHeight = Value
  156. End Set
  157. End Property
  158.  
  159. Public WriteOnly Property SetSubHeadHeight() As Integer
  160. Set(ByVal Value As Integer)
  161. SubHeadHeight = Value
  162. End Set
  163. End Property
  164.  
  165. Public WriteOnly Property SetFootHeight() As Integer
  166. Set(ByVal Value As Integer)
  167. FootHeight = Value
  168. End Set
  169. End Property
  170.  
  171. Public WriteOnly Property SetSubFootHeight() As Integer
  172. Set(ByVal Value As Integer)
  173. SubFootHeight = Value
  174. End Set
  175. End Property
  176.  
  177. Public WriteOnly Property SetCellHeight() As Integer
  178. Set(ByVal Value As Integer)
  179. YUnit = Value
  180. End Set
  181. End Property
  182.  
  183. Public Sub Print()
  184. Try
  185. DataTablePrinter = New Printing.PrintDocument
  186. AddHandler DataTablePrinter.PrintPage, AddressOf DataTablePrinter_PrintPage
  187. Dim PageSetup As PageSetupDialog
  188. PageSetup = New PageSetupDialog
  189. PageSetup.Document = DataTablePrinter
  190. DataTablePrinter.DefaultPageSettings = PageSetup.PageSettings
  191. If PageSetup.ShowDialog() = DialogResult.Cancel Then
  192. Exit Sub
  193. End If
  194. PLeft = DataTablePrinter.DefaultPageSettings.Margins.Left
  195. PTop = DataTablePrinter.DefaultPageSettings.Margins.Top
  196. PRight = DataTablePrinter.DefaultPageSettings.Margins.Right
  197. PBottom = DataTablePrinter.DefaultPageSettings.Margins.Bottom
  198. PWidth = DataTablePrinter.DefaultPageSettings.Bounds.Width
  199. PHeigh = DataTablePrinter.DefaultPageSettings.Bounds.Height
  200. '将当前页分成基本的单元
  201. XUnit = (PWidth - PLeft - PRight) / DataTablePrint.Columns.Count -
  202. PrintRecordNumber = (PHeigh - PTop - PBottom - HeadHeight - SubHeadHeight - FootHeight - SubFootHeight - YUnit) \ YUnit
  203. If DataTablePrint.Rows.Count > PrintRecordNumber Then
  204. If DataTablePrint.Rows.Count Mod PrintRecordNumber = Then
  205. TotalPage = DataTablePrint.Rows.Count \ PrintRecordNumber
  206. Else
  207. TotalPage = DataTablePrint.Rows.Count \ PrintRecordNumber +
  208. End If
  209. Else
  210. TotalPage =
  211. End If
  212. DataTablePrinter.DocumentName = TotalPage.ToString
  213. Dim PrintPriview As PrintPreviewDialog
  214. PrintPriview = New PrintPreviewDialog
  215. PrintPriview.Document = DataTablePrinter
  216. PrintPriview.WindowState = FormWindowState.Maximized
  217. PrintPriview.ShowDialog()
  218. Catch ex As Exception
  219. MsgBox("打印错误,请检查打印设置!", , "错误")
  220. End Try
  221. End Sub
  222.  
  223. Private Sub DataTablePrinter_PrintPage(ByVal sender As Object, ByVal Ev As System.Drawing.Printing.PrintPageEventArgs)
  224. '还有多少条记录没有打印
  225. PrintRecordLeave = DataTablePrint.Rows.Count - PrintRecordComplete
  226. If PrintRecordLeave > Then
  227. If PrintRecordLeave Mod PrintRecordNumber = Then
  228. PageNumber = PrintRecordLeave \ PrintRecordNumber
  229. Else
  230. PageNumber = PrintRecordLeave \ PrintRecordNumber +
  231. End If
  232. Else
  233. PageNumber =
  234. End If
  235. '正在打印的页数,因为每打印一个新页都要计算还有多少页没有打印所以以打印的页数初始为0
  236. PrintingPageNumber =
  237. '计算,余下的记录条数是否还可以在一页打印,不满一页时为假
  238. If DataTablePrint.Rows.Count - PrintingPageNumber * PrintRecordNumber >= PrintRecordNumber Then
  239. PageRecordNumber = PrintRecordNumber
  240. Else
  241. PageRecordNumber = (DataTablePrint.Rows.Count - PrintingPageNumber * PrintRecordNumber) Mod PrintRecordNumber
  242. End If
  243. Dim fmt As New StringFormat
  244. '上下对齐
  245. fmt.LineAlignment = StringAlignment.Center
  246. '自动换行
  247. fmt.FormatFlags = StringFormatFlags.LineLimit
  248. '打印区域
  249. Dim Rect As New Rectangle
  250. '打印表格线格式
  251. Dim Pen As New Pen(Brushes.Black, )
  252. While PrintingPageNumber <= PageNumber
  253. '表头中间对齐
  254. fmt.Alignment = StringAlignment.Center
  255. '表头和副表头宽度等于设置区域宽度
  256. Rect.Width = PWidth - PLeft - PRight
  257. Rect.Height = HeadHeight
  258. Rect.X = PLeft
  259. Rect.Y = PTop
  260. '打印表头
  261. Ev.Graphics.DrawString(HeadText, HeadFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
  262. '副表头左对齐
  263. fmt.Alignment = StringAlignment.Near
  264. Rect.Width = (PWidth - PLeft - PRight) / -
  265. Rect.Height = SubHeadHeight
  266. Rect.Y = PTop + HeadHeight
  267. '打印副表头左
  268. Ev.Graphics.DrawString(SubHeadLeftText, SubHeadFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
  269. '右副表头文字从右往左排列
  270. fmt.FormatFlags = StringFormatFlags.DirectionRightToLeft
  271. '右副表头右对齐
  272. fmt.Alignment = StringAlignment.Near
  273. Rect.X = PLeft + (PWidth - PLeft - PRight) /
  274. '打印副表头右
  275. Ev.Graphics.DrawString(SubHeadRightText, SubHeadFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
  276. fmt.Alignment = StringAlignment.Center
  277. Rect.X = PLeft
  278. Rect.Y = PTop + HeadHeight + SubHeadHeight + (PrintRecordNumber + ) * (YUnit) + SubFootHeight
  279. Rect.Height = FootHeight
  280. Rect.Width = PWidth - PLeft - PRight
  281. '打印表脚
  282. Ev.Graphics.DrawString(FootText, FootFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
  283. '副表左左对齐
  284. fmt.Alignment = StringAlignment.Far
  285. Rect.X = PLeft
  286. Rect.Y = PTop + HeadHeight + SubHeadHeight + (PrintRecordNumber + ) * (YUnit)
  287. Rect.Height = SubFootHeight
  288. Rect.Width = (PWidth - PLeft - PRight) / -
  289. '打印左表脚
  290. Ev.Graphics.DrawString(SubFootLeftText, SubFootFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
  291. '副表头右对齐
  292. fmt.Alignment = StringAlignment.Near
  293. Rect.X = PLeft + (PWidth - PLeft - PRight) /
  294. If DataTablePrint.Rows.Count = Then
  295. SubFootRightText = "第" & TotalPage & "页,共" & TotalPage & "页"
  296. Else
  297. SubFootRightText = "第" & TotalPage - PageNumber + & "页,共" & TotalPage & "页"
  298. End If
  299. '打印右表脚
  300. Ev.Graphics.DrawString(SubFootRightText, SubFootFont, Brushes.Black, RectangleF.op_Implicit(Rect), fmt)
  301. '得到datatable的所有列名
  302. fmt.Alignment = StringAlignment.Center
  303. Dim ColumnText(DataTablePrint.Columns.Count) As String
  304. For Cols = To DataTablePrint.Columns.Count -
  305. '得到当前所有的列名
  306. ColumnText(Cols) = DataTablePrint.Columns(Cols).ToString
  307. Rect.X = PLeft + XUnit * Cols
  308. Rect.Y = PTop + HeadHeight + SubHeadHeight
  309. Rect.Width = XUnit
  310. Rect.Height = YUnit
  311. Ev.Graphics.DrawString(ColumnText(Cols), New Font(TableFont, FontStyle.Bold), DrawBrush, RectangleF.op_Implicit(Rect), fmt)
  312. Ev.Graphics.DrawRectangle(Pen, Rect)
  313. Next
  314. '结束---------------------得到datatable的所有列名
  315. '当前页面已经打印的记录行数
  316. Dim PrintingLine As Integer =
  317. While PrintingLine < PageRecordNumber
  318. '确定要当前要打印的记录的行号
  319. DataGridRow = DataTablePrint.Rows(PrintRecordComplete)
  320. For Cols = To DataTablePrint.Columns.Count -
  321. Rect.X = PLeft + XUnit * Cols
  322. Rect.Y = PTop + HeadHeight + SubHeadHeight + (PrintingLine + ) * (YUnit)
  323. Rect.Width = XUnit
  324. Rect.Height = YUnit
  325. If DataGridRow(ColumnText(Cols)) Is System.DBNull.Value = False Then
  326. Ev.Graphics.DrawString(DataGridRow(ColumnText(Cols)), TableFont, DrawBrush, RectangleF.op_Implicit(Rect), fmt)
  327. End If
  328. Ev.Graphics.DrawRectangle(Pen, Rect)
  329. Next
  330. PrintingLine +=
  331. PrintRecordComplete +=
  332. If PrintRecordComplete >= DataTablePrint.Rows.Count Then
  333. Ev.HasMorePages = False
  334. PrintRecordComplete =
  335. Exit Sub
  336. End If
  337. End While
  338. PrintingPageNumber +=
  339. If PrintingPageNumber >= PageNumber Then
  340. Ev.HasMorePages = False
  341. Else
  342. Ev.HasMorePages = True
  343. Exit While
  344. End If
  345. End While
  346. End Sub
  347.  
  348. '附转换函数
  349. 'listview转为Datatable函数
  350. Public Function ListviewToDatatable(ByVal Listview1 As ListView)
  351. Dim Table1 As New DataTable
  352. Dim i As Integer
  353. Dim datacol As DataColumn
  354. For i = To Listview1.Columns.Count -
  355. datacol = New DataColumn
  356. datacol.DataType = Type.GetType("System.Object")
  357. datacol.ColumnName = Listview1.Columns(i).Text.Trim
  358. Table1.Columns.Add(datacol)
  359. Next i
  360. Dim j As Integer
  361. Dim Datarow1 As DataRow
  362. For j = To Listview1.Items.Count -
  363. Datarow1 = Table1.NewRow
  364. For i = To Listview1.Columns.Count -
  365. Datarow1.Item(Listview1.Columns(i).Text.Trim) = Listview1.Items(j).SubItems(i).Text.ToString
  366. Next i
  367. Table1.Rows.Add(Datarow1)
  368. Next j
  369. Return Table1
  370. End Function
  371.  
  372. '数据集转为Datatable函数
  373. Public Function DataBaseToDataTable(ByVal SqlDataAdapter1 As Data.SqlClient.SqlDataAdapter, ByVal TableName As String)
  374. Dim Table1 As New DataTable
  375. Dim DataSet1 As New DataSet
  376. DataSet1.Clear()
  377. SqlDataAdapter1.Fill(DataSet1, TableName)
  378. Table1 = DataSet1.Tables(TableName)
  379. Return Table1
  380. End Function
  381. End Class
  382.  
  383. Public Class FormPrintDataTable
  384.  
  385. Private Sub ButtonClickMe_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonClickMe.Click
  386. Dim SqlConn As New OleDb.OleDbConnection
  387. Dim SqlCmd As New OleDb.OleDbCommand
  388. Dim SqlAda As New OleDb.OleDbDataAdapter
  389. Dim Dt As New DataTable
  390. SqlConn.ConnectionString = "provider=microsoft.jet.oledb.4.0;data source=" & Application.StartupPath & "\data\data.mdb"
  391. SqlCmd.Connection = SqlConn
  392. SqlCmd.CommandText = "select * from [CARD]"
  393. SqlConn.Open()
  394. SqlAda.SelectCommand = SqlCmd
  395. SqlAda.Fill(Dt)
  396. SqlCmd.Cancel()
  397. SqlConn.Close()
  398. Dim PDt As New PrintDataTable(Dt)
  399. PDt.SetHeadText = "XXXX煤矿报表测试"
  400. PDt.SetFootText = "矿长签字: 总工签字: 值班人员签字:"
  401. PDt.SetSubHeadLeftText = "数据时间:" & Now.Date
  402. PDt.SetSubHeadRightText = "打印时间:" & Now.Date
  403. PDt.Print()
  404. End Sub
  405. End Class

如何绘制表格2

  1. public class PrintFunction
  2. {
  3. public String printName = String.Empty;
  4. public Font prtTextFont = new Font("Verdana", );
  5. public Font prtTitleFont = new Font("宋体", );
  6. private String[] titles = new String[];
  7. public String[] Titles
  8. {
  9. set
  10. {
  11. titles = value as String[];
  12. if (null == titles)
  13. {
  14. titles = new String[];
  15. }
  16. }
  17. get
  18. {
  19. return titles;
  20. }
  21. }
  22. private Int32 left = ;
  23. private Int32 top = ;
  24. public Int32 Top
  25. {
  26. set
  27. {
  28. top = value;
  29. }
  30. get
  31. {
  32. return top;
  33. }
  34. }
  35. public Int32 Left
  36. {
  37. set
  38. {
  39. left = value;
  40. }
  41. get
  42. {
  43. return left;
  44. }
  45. }
  46. private DataTable printedTable;
  47. private Int32 pheight;
  48. private Int32 pWidth;
  49. private Int32 pindex;
  50. private Int32 curdgi;
  51. private Int32[] width;
  52. private Int32 rowOfDownDistance = ;
  53. private Int32 rowOfUpDistance = ;
  54. public Boolean PrintDataTable(DataTable table)
  55. {
  56. PrintDocument prtDocument = new PrintDocument();
  57. try
  58. {
  59. if (printName != String.Empty)
  60. {
  61. prtDocument.PrinterSettings.PrinterName = printName;
  62. }
  63. prtDocument.DefaultPageSettings.Landscape = true;
  64. prtDocument.OriginAtMargins = false;
  65. PrintDialog prtDialog = new PrintDialog();
  66. prtDialog.AllowSomePages = true;
  67.  
  68. prtDialog.ShowHelp = false;
  69. prtDialog.Document = prtDocument;
  70.  
  71. if (DialogResult.OK != prtDialog.ShowDialog())
  72. {
  73. return false;
  74. }
  75.  
  76. printedTable = table;
  77. pindex = ;
  78. curdgi = ;
  79. width = new Int32[printedTable.Columns.Count];
  80. pheight = prtDocument.PrinterSettings.DefaultPageSettings.Bounds.Bottom;
  81. pWidth = prtDocument.PrinterSettings.DefaultPageSettings.Bounds.Right;
  82.  
  83. prtDocument.PrintPage += new PrintPageEventHandler(Document_PrintPage);
  84.  
  85. prtDocument.Print();
  86.  
  87. }
  88. catch( InvalidPrinterException ex )
  89. {
  90. MessageBox.Show("没有安装打印机");
  91. }
  92. catch (Exception ex)
  93. {
  94. MessageBox.Show("打印错误");
  95. }
  96. prtDocument.Dispose();
  97. return true;
  98. }
  99.  
  100. Int32 startColumnControls = ;
  101. Int32 endColumnControls = ;
  102. private void Document_PrintPage(object sender, PrintPageEventArgs ev)
  103. {
  104. Int32 x = left;
  105. Int32 y = top;
  106. Int32 rowOfTop = top;
  107. Int32 i;
  108. Pen pen = new Pen(Brushes.Black, );
  109. if ( == pindex)
  110. {
  111. for (i = ; i < titles.Length; i++)
  112. {
  113. ev.Graphics.DrawString(titles[i], prtTitleFont, Brushes.Black, left, y + rowOfUpDistance);
  114. y += prtTextFont.Height + rowOfDownDistance;
  115. }
  116. rowOfTop = y;
  117. foreach(DataRow dr in printedTable.Rows)
  118. {
  119. for (i = ; i < printedTable.Columns.Count; i++)
  120. {
  121. Int32 colwidth = Convert.ToInt16(ev.Graphics.MeasureString(dr[i].ToString().Trim(), prtTextFont).Width);
  122. if (colwidth>width[i])
  123. {
  124. width[i] = colwidth;
  125. }
  126. }
  127. }
  128. }
  129. for (i = endColumnControls; i < printedTable.Columns.Count; i++)
  130. {
  131. String headtext = printedTable.Columns[i].ColumnName.Trim();
  132. if (pindex == )
  133. {
  134. int colwidth = Convert.ToInt16(ev.Graphics.MeasureString(headtext, prtTextFont).Width);
  135. if (colwidth > width[i])
  136. {
  137. width[i] = colwidth;
  138. }
  139. }
  140. if (x + width[i] > pheight)
  141. {
  142. break;
  143. }
  144. ev.Graphics.DrawString(headtext, prtTextFont, Brushes.Black, x, y + rowOfUpDistance);
  145. x += width[i];
  146. }
  147. startColumnControls = endColumnControls;
  148. if (i < printedTable.Columns.Count)
  149. {
  150. endColumnControls = i;
  151. ev.HasMorePages = true;
  152. }
  153. else
  154. {
  155. endColumnControls = printedTable.Columns.Count;
  156. }
  157. ev.Graphics.DrawLine(pen, left, rowOfTop, x, rowOfTop);
  158. y += rowOfUpDistance + prtTextFont.Height + rowOfDownDistance;
  159. ev.Graphics.DrawLine(pen, left, y, x, y);
  160. for (i = curdgi; i < printedTable.Rows.Count; i++)
  161. {
  162. x = left;
  163. for (Int32 j = startColumnControls; j < endColumnControls; j++)
  164. {
  165. ev.Graphics.DrawString(printedTable.Rows[i][j].ToString().Trim(), prtTextFont, Brushes.Black, x, y + rowOfUpDistance);
  166. x += width[j];
  167. }
  168. y += rowOfUpDistance + prtTextFont.Height + rowOfDownDistance;
  169. ev.Graphics.DrawLine(pen, left, y, x, y);
  170. if (y > pWidth - prtTextFont.Height - )
  171. {
  172. break;
  173. }
  174. }
  175. ev.Graphics.DrawLine(pen, left, rowOfTop, left, y);
  176. x = left;
  177. for (Int32 k = startColumnControls; k < endColumnControls; k++)
  178. {
  179. x += width[k];
  180. ev.Graphics.DrawLine(pen, x, rowOfTop, x, y);
  181. }
  182. if (y > pWidth - prtTextFont.Height - )
  183. {
  184. pindex++;
  185. if ( != startColumnControls)
  186. {
  187. curdgi = i + ;
  188. }
  189. if (!ev.HasMorePages)
  190. {
  191. endColumnControls = ;
  192. }
  193. ev.HasMorePages = true;
  194. }
  195. }
  196. public void PrintPreviewDataTable(DataTable prtTable)
  197. {
  198. PrintDocument prtDocument = new PrintDocument();
  199. try
  200. {
  201. if (printName != String.Empty)
  202. {
  203. prtDocument.PrinterSettings.PrinterName = printName;
  204.  
  205. }
  206. prtDocument.DefaultPageSettings.Landscape = true;
  207. prtDocument.OriginAtMargins = false;
  208. printedTable = prtTable;
  209. pindex = ;
  210. curdgi = ;
  211. width = new int[printedTable.Columns.Count];
  212. pheight = prtDocument.PrinterSettings.DefaultPageSettings.Bounds.Bottom;
  213. pWidth = prtDocument.PrinterSettings.DefaultPageSettings.Bounds.Right;
  214. prtDocument.PrintPage += new PrintPageEventHandler(Document_PrintPage);
  215. PrintPreviewDialog prtPreviewDialog = new PrintPreviewDialog();
  216. prtPreviewDialog.Document = prtDocument;
  217. prtPreviewDialog.ShowIcon = false;
  218. prtPreviewDialog.WindowState = FormWindowState.Maximized;
  219. prtPreviewDialog.ShowDialog();
  220.  
  221. }
  222. catch (InvalidPrinterException ex)
  223. {
  224. MessageBox.Show("没有安装打印机");
  225. }
  226. catch (Exception ex)
  227. {
  228. MessageBox.Show("打印预览失败");
  229. }
  230.  
  231. }
  232. }

C# 使用PrintDocument 绘制表格 完成 打印预览的更多相关文章

  1. C# 使用PrintDocument 绘制表格 完成 打印预览 DataTable

    经过不断的Google与baidu,最终整理出来的打印类 主要是根据两个参考的类组合而成,稍微修改了一下,参考代码及来源见最后(其中一份是VB语言的) 其中遇到的一些问题也已经得到了解决(分页,打印预 ...

  2. 【转】C#使用PrintDocument打印 多页 打印预览

    PrintDocument实例所有的订阅事件如下: 创建一个PrintDocument的实例.如下: System.Drawing.Printing.PrintDocument docToPrint ...

  3. C#使用PrintDocument打印 多页 打印预览

    PrintDocument实例所有的订阅事件如下: 创建一个PrintDocument的实例.如下: System.Drawing.Printing.PrintDocument docToPrint ...

  4. C#教程之打印和打印预览

    最近研究一了一下关于PDF打印和打印预览的功能,在此小小的总结记录一下学习过程. 实现打印和打印预览的方法,一般要实现如下的菜单项:打印.打印预览.页面设置. PrintDocument类 Print ...

  5. C#实现打印与打印预览功能

    C#实现打印与打印预览功能的思路及代码. 在windows应用程序中文档的打印是一项非常重要的功能,在以前一直是一个非常复杂的工作,Microsoft .Net Framework的打印功能都以组件的 ...

  6. C#实现打印与打印预览功能(转)

    在windows应用程序中文档的打印是一项非常重要的功能,在以前一直是一个非常复杂的工作,Microsoft .Net Framework的打印功能都以组件的方式提供,为程序员提供了很大的方便,但是这 ...

  7. MyReport:DataGrid的打印和打印预览

    本文说明怎样使用MyReport来实现Flex DataGrid组件的自己主动化打印预览和打印功能. 实现代码 <? xmlversion="1.0" encoding=&q ...

  8. winForm 打印预览

    自己很少写技术博客,虽然已经干程序员两年多了,winform开发,web开发都干过,不论项目大小对于.net的相关技术也是了解的,如mvc,wcf,wpf,silverlight,socekt通讯,n ...

  9. JavaScript 实现打印,打印预览,打印设置

    WebBrowser是IE内置的浏览器控件,无需用户下载. 一.WebBrowser控件 <object ID='WebBrowser' WIDTH=0 HEIGHT=0 CLASSID='CL ...

随机推荐

  1. samba 二进制包 tar.gz 安装

    一.下载 sudo wget https://download.samba.org/pub/samba/stable/samba-4.8.10.tar.gz 二.解压 sudu tar -xvzf s ...

  2. 爬虫----beautifulsoup的简单使用

    beautifulSoup使用: 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据. pip3 install beautifulsoup4 解析器 Beau ...

  3. redis 单实例安装

    单实例安装 近些年,由于内存技术的提升.造价的下降,越来越多企业的服务器内存已增加到几百G.这样的内存容量给了内存数据库一个良好的发展环境. 而使用Redis是内存数据库的一股清流,渐有洪大之势.下面 ...

  4. Django_Admin操作

    Django_Admin 创建Django_Admin 管理账户 D:\github\Django_Aadmin>python manage.py createsuperuser Usernam ...

  5. [转] Node.js使用MongoDB3.4+Access control is not enabled for the database解决方案

    今天使用MongoDB时遇到了一些问题 建立数据库连接时出现了warnings 出现这个警告的原因是新版本的MongDB为了让我们创建一个安全的数据库 必须要进行验证 后来在外网找到了答案 解决方案如 ...

  6. C# 多线程下 静态类字段异常

  7. 安装CentOS 7(转)

    转载地址:https://www.cnblogs.com/wcwen1990/p/7630545.html CentOS7安装详解   本文基于vmware workstations进行CentOS7 ...

  8. 【bzoj3174】[Tjoi2013]拯救小矮人

    题解: 这题非常容易想到一个错误的贪心 就是按照ai排序 然后尽量取ai小的 但是有很明显的问题就是如果取了小的ai 那会导致那些原本可能存在这些ai就可以去掉的大的人因此不能取了 而有可能可以先去取 ...

  9. AtCoder Regular Contest 102 (ARC102) D All Your Paths are Different Lengths 构造

    原文链接https://www.cnblogs.com/zhouzhendong/p/ARC102D.html 题目传送门 - ARC102D 题意 给定 $L$,请你构造一个节点个数为 $n$ ,边 ...

  10. datatable 转list ,list转datatable

    方法一:  public static IList<T> ConvertToModel(DataTable dt)             {                // 定义集合 ...