PrintHelper.cs 14 KB

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