MisGoldPrinter.cs
上传用户:jx_fiona
上传日期:2014-03-08
资源大小:1387k
文件大小:27k
源码类别:

打印编程

开发平台:

Others

  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Printing;
  4. using winForm = System.Windows.Forms;
  5. //《MIS金质打印通》一下版,敬请关注...
  6. // Web打印、XML解析、二次开发,全面支持... 
  7. //   丰富格式、自由设计、人人参预打印平台...
  8. namespace GoldPrinter
  9. {
  10. /// <summary>
  11. /// 本程序为通用打印程序,单据、会计凭证、发票清单、报表、任意复杂表格、合并表格如工矿企业合同都可以由系统提供的几个默。
  12. /// 认打印对象组合打印。
  13. /// DataGrid、DataTable、MSHFlexGrid等二维形式全部可以打印。
  14. /// 部分对象如PrinterMargins、Sewing、GridLineFlag、GridMergeFlag等提供图例,以促进理解。
  15. /// 后期版本将提供XML描述、SQL数据源的打印,并用管理器管理任意多个网格、文本对象、图象等,用户可以随意定义。
  16. /// 
  17. /// 作 者:长江支流(周方勇)
  18. /// Email:flygoldfish@163.com  QQ:150439795
  19. /// 网 址:www.webmis.com.cn
  20. /// ★★★★★您可以免费使用此程序,但是请您完整保留此说明,以维护知识产权★★★★★
  21. /// 
  22. /// </summary>
  23. public class MisGoldPrinter:IDisposable
  24. {
  25. //打印对象之间的距离
  26. private const int CON_SPACE_TITLE_CAPTION = 5;
  27. private const int CON_SPACE_CAPTION_TOP = 20;
  28. private const int CON_SPACE_HEADER_BODY = 5;
  29. private const int CON_SPACE_BODY_FOOTER = 5;
  30. //下一对象的起点坐标及宽
  31. private int X,Y,Width;
  32. //缩放比
  33. private float Scale = 1.0F;
  34. //翻页用
  35. private int mCurrentPageIndex; //当前页
  36. private int mCurrentRowIndex; //主数据网格的当前行
  37. //绘图表面
  38. private Graphics mGraphics;
  39. private Printer mPrinter;
  40. //打印文档
  41. private PrintDocument mPrintDocument;
  42. //打印区
  43. private PrinterMargins mPrinterMargins;
  44. //装订,对象的线长小于0则自动设置
  45. private Sewing _sewing;
  46. private bool _isOnlySingleColor = true; //仅仅单色(黑色)打印
  47. public Color BackColor = Color.White; //背景颜色
  48. #region 字段属性
  49. /// <summary>
  50. /// 装订对象,对象的线长小于0则自动设置,为null时不起作用。注意是全局的
  51. /// </summary>
  52. public Sewing Sewing
  53. {
  54. get
  55. {
  56. return this._sewing;
  57. }
  58. set
  59. {
  60. if (value != null)
  61. {
  62. this._sewing = value;
  63. }
  64. else
  65. {
  66. this._sewing.Margin = 0; //宽度为0则不打印
  67. }
  68. }
  69. }
  70. public string DocumentName
  71. {
  72. get
  73. {
  74. return this.mPrintDocument.DocumentName;
  75. }
  76. set
  77. {
  78. this.mPrintDocument.DocumentName = value;
  79. }
  80. }
  81. #endregion
  82. //字段
  83. private int _rowsPerPage = -1;   //每页行数,小于等于0自适应,默认
  84. private bool _isSubTotalPerPage = false; //是否每页都要显示主数据网格当前页小计(默认否)
  85. private string _subTotalColsList = ""; //每页小计要指定的列
  86. private bool _isSewingLine = false; //是否打印装订线(默认无)
  87. private bool _isPrinterMargins = false; //是否打印有效区域矩阵(默认无)
  88. private GridBorderFlag _gridBorder = GridBorderFlag.Double; //网格边框(默认双边框)
  89. #region 字段属性
  90. /// <summary>
  91. /// 每页行数,小于等于0自适应,默认
  92. /// </summary>
  93. public int RowsPerPage
  94. {
  95. get
  96. {
  97. return _rowsPerPage;
  98. }
  99. set
  100. {
  101. _rowsPerPage = value;
  102. }
  103. }
  104. /// <summary>
  105. /// 是否每页都要显示当前页小计(默认否)
  106. /// </summary>
  107. public bool IsSubTotalPerPage
  108. {
  109. get
  110. {
  111. return _isSubTotalPerPage;
  112. }
  113. set
  114. {
  115. _isSubTotalPerPage = value;
  116. }
  117. }
  118. /// <summary>
  119. /// 用分号分隔的要每页小计列
  120. /// </summary>
  121. public string SubTotalColsList
  122. {
  123. get
  124. {
  125. return _subTotalColsList;
  126. }
  127. set
  128. {
  129. _subTotalColsList = value;
  130. }
  131. }
  132. /// <summary>
  133. /// 是否打印装订线,对象的线长小于等于0则自动设置
  134. /// </summary>
  135. public bool IsSewingLine
  136. {
  137. get
  138. {
  139. return _isSewingLine;
  140. }
  141. set
  142. {
  143. _isSewingLine = value;
  144. }
  145. }
  146. /// <summary>
  147. /// 是否打印有效区域矩阵
  148. /// </summary>
  149. public bool IsPrinterMargins
  150. {
  151. get
  152. {
  153. return _isPrinterMargins;
  154. }
  155. set
  156. {
  157. _isPrinterMargins = value;
  158. }
  159. }
  160. /// <summary>
  161. /// 网格边框
  162. /// </summary>
  163. public GridBorderFlag GridBorder
  164. {
  165. get
  166. {
  167. return this._gridBorder;
  168. }
  169. set
  170. {
  171. this._gridBorder = value;
  172. }
  173. }
  174. #endregion
  175. //********************打印对象********************
  176. private Title _title; //主标题
  177. private Caption _caption; //副标题
  178. private Top _top; //简单的一行三列打印样式,第一列居左,第三列居右,中间列居中
  179. private Header _header; //正文网格主体之上的几行几列的标注说明
  180. private MultiHeader _multiHeader; //正文网格主体标题头可能需要多层合并表头说明
  181. private Body _body; //*正文网格主体,必须,打印以此为基准
  182. protected Footer _footer; //正文网格主体之下的几行几列的标注说明
  183. private Bottom _bottom; //简单的一行三列打印样式,第一列居左,第三列居右,中间列居中
  184. #region 打印对象字段属性
  185. #region Title、Caption 标题、副标题
  186. /// <summary>
  187. /// 获取或设置打印主标题,可以是文本,也可以是定义更多特性的Title对象
  188. /// </summary>
  189. public object Title
  190. {
  191. get
  192. {
  193. return this._title;
  194. }
  195. set
  196. {
  197. if (value != null)
  198. {
  199. if (value.GetType().ToString() == "System.String")
  200. {
  201. if (this._title == null)
  202. {
  203. this._title = new Title();
  204. }
  205. this._title.Text = (string)value;
  206. }
  207. else if(value.GetType().ToString() == "GoldPrinter.Title")
  208. {
  209. this._title = (GoldPrinter.Title)value;
  210. }
  211. }
  212. }
  213. }
  214. /// <summary>
  215. /// 获取或设置打印副标题,可以是文本,也可以是定义更多特性的Caption对象
  216. /// </summary>
  217. public object Caption
  218. {
  219. get
  220. {
  221. return this._caption;
  222. }
  223. set
  224. {
  225. if (value != null)
  226. {
  227. if (value.GetType().ToString() == "System.String")
  228. {
  229. if (this._caption == null)
  230. {
  231. this._caption = new Caption();
  232. }
  233. this._caption.Text = (string)value;
  234. }
  235. else if(value.GetType().ToString() == "GoldPrinter.Caption")
  236. {
  237. this._caption = (GoldPrinter.Caption)value;
  238. }
  239. }
  240. }
  241. }
  242. #endregion
  243. #region 获取或设置网格顶、底,可以是以'|'分隔的字符串或一维数组或具有更多特性的Top/Bottom对象
  244. /// <summary>
  245. /// 或取或设置网格头,可以是以'|'分隔的字符串或或一维数组或具有更多特性的Top对象
  246. /// </summary>
  247. public object Top
  248. {
  249. get
  250. {
  251. return this._top;
  252. }
  253. set
  254. {
  255. if (value != null)
  256. {
  257. if (value.GetType().ToString() == "System.String" || value.GetType().ToString() == "System.String[]")
  258. {
  259. if (this._top == null)
  260. {
  261. this._top = new Top();
  262. }
  263. this._top.DataSource = value;
  264. }
  265. else if(value.GetType().ToString() == "GoldPrinter.Top")
  266. {
  267. this._top = (GoldPrinter.Top)value;
  268. }
  269. }
  270. }
  271. }
  272. /// <summary>
  273. /// 或取或设置网格底,可以是以'|'分隔的字符串或或一维数组或具有更多特性的Bottom对象
  274. /// </summary>
  275. public object Bottom
  276. {
  277. get
  278. {
  279. return this._bottom;
  280. }
  281. set
  282. {
  283. if (value != null)
  284. {
  285. if (value.GetType().ToString() == "System.String" || value.GetType().ToString() == "System.String[]")
  286. {
  287. if (this._bottom == null)
  288. {
  289. this._bottom = new Bottom();
  290. }
  291. this._bottom.DataSource = (string)value;
  292. }
  293. else if(value.GetType().ToString() == "GoldPrinter.Bottom")
  294. {
  295. this._bottom = (GoldPrinter.Bottom)value;
  296. }
  297. }
  298. }
  299. }
  300. #endregion
  301. #region 获取或设置网格头部、下部,可以是一维数组、二维数组、或DataTable或具有更多特性的Header/Footer对象
  302. /// <summary>
  303. /// 或取或设置网格头部说明部分,可以是一维数组、二维数组、或DataTable或Header等
  304. /// </summary>
  305. public object Header
  306. {
  307. get
  308. {
  309. return _header;
  310. }
  311. set
  312. {
  313. if (value != null)
  314. {
  315. if (value.GetType().ToString() == "System.String[]" || value.GetType().ToString() == "System.String[,]" || value.GetType().ToString() == "System.Data.DataTable")
  316. {
  317. if (this._header == null)
  318. {
  319. this._header = new Header();
  320. }
  321. this._header.DataSource = value;
  322. }
  323. else if(value.GetType().ToString() == "GoldPrinter.Header")
  324. {
  325. this._header = (GoldPrinter.Header)value;
  326. }
  327. }
  328. }
  329. }
  330. /// <summary>
  331. /// 或取或设置网格下部说明部分,可以是一维数组、二维数组、或DataTable或Footer等等
  332. /// </summary>
  333. public object Footer
  334. {
  335. get
  336. {
  337. return this._footer;
  338. }
  339. set
  340. {
  341. if (value != null)
  342. {
  343. if (value.GetType().ToString() == "System.String[]" || value.GetType().ToString() == "System.String[,]" || value.GetType().ToString() == "System.Data.DataTable")
  344. {
  345. if (this._footer == null)
  346. {
  347. this._footer = new Footer();
  348. }
  349. this._footer.DataSource = value;
  350. }
  351. else if(value.GetType().ToString() == "GoldPrinter.Footer")
  352. {
  353. this._footer = (GoldPrinter.Footer)value;
  354. }
  355. }
  356. }
  357. }
  358. #endregion
  359. #region 获取或设置网格体及对应的标题,可以是一维数组、二维数组、或DataTable或具有更多特性的MultiHeader/Body对象
  360. /// <summary>
  361. /// 获取或设置网格体对应的标题,可以是一维数组、二维数组、或DataTable或具有更多特性的MultiHeader
  362. /// </summary>
  363. public object MultiHeader
  364. {
  365. get
  366. {
  367. return _multiHeader;
  368. }
  369. set
  370. {
  371. if (value != null)
  372. {
  373. if (value.GetType().ToString() == "System.String[]" || value.GetType().ToString() == "System.String[,]" || value.GetType().ToString() == "System.Data.DataTable")
  374. {
  375. if (this._multiHeader == null)
  376. {
  377. this._multiHeader = new MultiHeader();
  378. }
  379. this._multiHeader.DataSource = value;
  380. }
  381. else if(value.GetType().ToString() == "GoldPrinter.MultiHeader")
  382. {
  383. this._multiHeader = (GoldPrinter.MultiHeader)value;
  384. }
  385. }
  386. }
  387. }
  388. /// <summary>
  389. /// 获取或设置网格体,可以是一维数组、二维数组、或DataTable或具有更多特性的Body
  390. /// </summary>
  391. public object Body
  392. {
  393. get
  394. {
  395. return _body;
  396. }
  397. set
  398. {
  399. if (value != null)
  400. {
  401. if (value.GetType().ToString() == "System.String[]" || value.GetType().ToString() == "System.String[,]" || value.GetType().ToString() == "System.Data.DataTable")
  402. {
  403. if (this._body == null)
  404. {
  405. this._body = new Body();
  406. }
  407. this._body.DataSource = value;
  408. }
  409. else if(value.GetType().ToString() == "GoldPrinter.Body")
  410. {
  411. this._body = (GoldPrinter.Body)value;
  412. }
  413. }
  414. }
  415. }
  416. #endregion
  417. #endregion
  418. //还可以将此程序稍微修改,用一个集体管理,动态加载打印对象,形成任意多个网格的组合体,打印任意复杂的网格
  419. public MisGoldPrinter():this(false)
  420. {
  421. }
  422. public MisGoldPrinter(bool p_IsLandscape)
  423. {
  424. PrinterSingleton.Reset();
  425. mCurrentPageIndex = 1;
  426. mCurrentRowIndex = 0;
  427. //单一模式,全部打印对象使用下面相同的对象,提高打印速度效率
  428. mPrintDocument = PrinterSingleton.PrintDocument;
  429. mPrintDocument.DefaultPageSettings.Landscape = p_IsLandscape;
  430. mPrinterMargins = PrinterSingleton.PrinterMargins;
  431. mPrintDocument.DocumentName = "MIS金质打印通,欢迎使用!";
  432. _sewing = new Sewing(30,SewingDirectionFlag.Left);
  433. mPrinter = new Printer();
  434. _body = new Body(); //主要对象,所以实例化
  435. }
  436. #region IDisposable 成员
  437. public virtual void Dispose()
  438. {
  439. try
  440. {
  441. mGraphics.Dispose();
  442. mPrintDocument.Dispose();
  443. }
  444. catch{}
  445. }
  446. #endregion
  447. /// <summary>
  448. /// 获取或设置数据主体网格的数据源,可以是一维数组、二维数组、或DataTable或DataGrid、MshFlexGrid、HtmlTable等二维网格,不支持的自己转换成二维数组
  449. /// </summary>
  450. public object DataSource
  451. {
  452. get
  453. {
  454. return this._body.DataSource;
  455. }
  456. set
  457. {
  458. this._body.DataSource = value;
  459. }
  460. }
  461. /// <summary>
  462. /// 页面设置对话框。
  463. /// </summary>
  464. public System.Drawing.Printing.PageSettings PageSetup()
  465. {
  466. PrinterPageSetting printerPageSetting;
  467. printerPageSetting = new PrinterPageSetting(mPrintDocument);
  468. printerPageSetting.PrintPage += new PrintPageDelegate(this.PrintPageEventHandler);
  469. PageSettings pstBack = mPrintDocument.DefaultPageSettings;
  470. PageSettings pstNew = printerPageSetting.ShowPageSetupDialog();
  471. if (pstBack != pstNew)
  472. {
  473. //改变页面设置后,单件重置
  474. PrinterSingleton.PrintDocument = mPrintDocument;
  475. mPrinterMargins = new PrinterMargins(mPrintDocument);
  476. PrinterSingleton.PrinterMargins = mPrinterMargins;
  477. }
  478. return pstNew;
  479. }
  480. /// <summary>
  481. /// 打印设置对话框。
  482. /// </summary>
  483. public System.Drawing.Printing.PrinterSettings Print()
  484. {
  485. this.mCurrentPageIndex = 1;
  486. this.mCurrentRowIndex = 0;
  487. PrinterPageSetting printerPageSetting;
  488. printerPageSetting = new PrinterPageSetting(mPrintDocument);
  489. printerPageSetting.PrintPage += new PrintPageDelegate(this.PrintPageEventHandler);
  490. return printerPageSetting.ShowPrintSetupDialog();
  491. }
  492. /// <summary>
  493. /// 打印预览对话框。
  494. /// </summary>
  495. public void Preview()
  496. {
  497. this.mCurrentPageIndex = 1;
  498. this.mCurrentRowIndex = 0;
  499. PrinterPageSetting printerPageSetting;
  500. printerPageSetting = new PrinterPageSetting(mPrintDocument);
  501. printerPageSetting.PrintPage += new PrintPageDelegate(this.PrintPageEventHandler);
  502. //导出到Excel方法实现
  503. printerPageSetting.ImportExcelValue = new ImportExcelDelegate(this.ImportExcelMethodHandler);
  504. printerPageSetting.ShowPrintPreviewDialog();
  505. }
  506. public void ImportExcelMethodHandler(Object obj,ImportExcelArgs ev)
  507. {
  508. #region 实现...
  509. ExcelAccess excel = new ExcelAccess();
  510. excel.Open();
  511. excel.MergeCells(1,1,1,this._body.Cols); //合并单元格写标题,并设置字体
  512. excel.SetFont(1,1,1,this._body.Cols,this._title.Font);
  513. excel.SetCellText(1,1,1,this._body.Cols,this._title.Text);
  514. //打印网格及网格线
  515. excel.SetCellText((System.Data.DataTable)this.DataSource,3,1,true);
  516. System.Windows.Forms.FileDialog fileDlg = new System.Windows.Forms.SaveFileDialog();
  517. fileDlg.AddExtension = true;
  518. fileDlg.DefaultExt = ".xls";
  519. //fileDlg.InitialDirectory = System.IO.Directory.GetCurrentDirectory();
  520. fileDlg.Title = "保存到Excel文件";
  521. fileDlg.Filter = "Microsoft Office Excel 工作簿(*.xls)|*.xls|模板(*.xlt)|*.xlt";
  522. if (fileDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
  523. {
  524. if (excel.SaveAs(fileDlg.FileName,true))
  525. {
  526. System.Windows.Forms.MessageBox.Show("数据成功保存到Excel文件!","GoldPrinter",System.Windows.Forms.MessageBoxButtons.OK,System.Windows.Forms.MessageBoxIcon.Information);
  527. }
  528. }
  529. fileDlg.Dispose();
  530. excel.Close();
  531. #endregion
  532. }
  533. //绘制
  534. private void PrintPageEventHandler(object obj,System.Drawing.Printing.PrintPageEventArgs ev)
  535. {
  536. Graphics g = ev.Graphics ;
  537. this.mGraphics = g;
  538. //g.Clear(this.BackColor);
  539. //WriteMetricsToConsole(ev);
  540. try
  541. {
  542. bool blnMore = this.Draw(g);
  543. if (blnMore)
  544. {
  545. ev.HasMorePages = true;
  546. mCurrentPageIndex++;
  547. }
  548. else
  549. {
  550. ev.HasMorePages = false;
  551. //打印或预览完毕后重置,以免在预览窗口中打印时打不出网格体Body
  552. this.mCurrentPageIndex = 1;
  553. this.mCurrentRowIndex = 0;
  554. }
  555. }
  556. catch(Exception e)
  557. {
  558. //System.Windows.Forms.MessageBox.Show(e.Message);
  559. }
  560. }
  561. /// 对象打印接口
  562. private void OutObject(Printer outer)
  563. {
  564. if (outer != null)
  565. {
  566. outer.Graphics = this.mGraphics;
  567. outer.Rectangle = new Rectangle(X,Y,Width,outer.Height);
  568. if (this._isOnlySingleColor)
  569. {
  570. outer.Pen = Pens.Black;
  571. outer.Brush = Brushes.Black;
  572. }
  573. outer.Draw();
  574. this.Y  += outer.Rectangle.Height;
  575. }
  576. }
  577. #region 绘制过程
  578. /// <summary>
  579. /// 绘制过程
  580. /// </summary>
  581. /// <param name="g"></param>
  582. /// <returns>一页没绘制完返回false</returns>
  583. private bool Draw(Graphics g)
  584. {
  585. bool blnHasMorePage = false; //是否还有下一页标记
  586. if (this._body.Rows < 0)
  587. {
  588. throw new Exception("打印主要网格不能为空,请用Body设置!");
  589. }
  590. mPrinter.Graphics = g;
  591. mPrinter.PrintDocument = this.mPrintDocument;
  592. mPrinter.Sewing = this.Sewing;
  593. mPrinter.PrinterMargins = this.mPrinterMargins; 
  594. //初起打印起点坐标及打印区域的宽
  595. Y = mPrinter.PrinterMargins.Top;
  596. X = mPrinter.PrinterMargins.Left;
  597. Width = mPrinter.PrinterMargins.Width;
  598.                        
  599. //画打印区域及装订线
  600. this.DrawPrinterMargins(mPrinter);
  601. this.DrawSewing(mPrinter);
  602. //正标题每页必重复打印,无需判断(改了,更多选择吧)
  603. if (_title != null && (mCurrentPageIndex == 1 || _title.IsDrawAllPage))
  604. {
  605. _title.PrinterMargins = mPrinterMargins;
  606. OutObject(_title);
  607. }
  608. if (_caption != null && (mCurrentPageIndex == 1 || _caption.IsDrawAllPage))
  609. {
  610. _caption.MoveY = 0;
  611. if (_title != null && (mCurrentPageIndex == 1 || _title.IsDrawAllPage))
  612. {
  613. _caption.MoveY = (int)this._title.Height + CON_SPACE_TITLE_CAPTION;
  614. }
  615. _caption.PrinterMargins = mPrinterMargins;
  616. OutObject(_caption);
  617. }
  618. if (_title != null || _caption != null)
  619. {
  620. Y += CON_SPACE_CAPTION_TOP; //标题与下面有一定距离
  621. }
  622. //启用实际宽度
  623. int lngInfactWidth = 0;
  624. if (!this._body.IsAverageColsWidth)
  625. {
  626. for(int i=0;i<_body.ColsWidth.Length;i++)
  627. {
  628. lngInfactWidth += _body.ColsWidth[i];
  629. }
  630. if (lngInfactWidth > this.mPrinterMargins.Width)
  631. {
  632. //缩放
  633. Scale = this.mPrinterMargins.Width/lngInfactWidth;
  634. }
  635. else
  636. {
  637. Width = lngInfactWidth;
  638. X += (this.mPrinterMargins.Width - Width)/2;
  639. }
  640. }
  641. if (_top != null && (mCurrentPageIndex == 1 || _top.IsDrawAllPage))
  642. {
  643. OutObject(_top);
  644. }
  645. if (_header != null && (mCurrentPageIndex == 1 || _header.IsDrawAllPage))
  646. {
  647. OutObject(_header);
  648. }
  649. if ((_top != null || _header != null) && (mCurrentPageIndex == 1 || (_top != null && _top.IsDrawAllPage) || (_header != null && _header.IsDrawAllPage)))
  650. {
  651. Y += CON_SPACE_HEADER_BODY; //网格与页头距离
  652. }
  653. if (_multiHeader != null && (mCurrentPageIndex == 1 || _multiHeader.IsDrawAllPage))
  654. {
  655. OutObject(_multiHeader);
  656. }
  657.             
  658. #region 主体数据网格
  659. //TimeDef.Start();
  660. //计算有效高度,便于分页
  661. float validHeight = mPrinter.PrinterMargins.Height - (Y - mPrinter.PrinterMargins.Top);
  662. if(_footer != null && _footer.IsDrawAllPage)
  663. {
  664. validHeight -= this._footer.Height;
  665. }
  666. if(_bottom != null && _bottom.IsDrawAllPage)
  667. {
  668. validHeight -= this._bottom.Height;
  669. }
  670. if (validHeight < 0)
  671. {
  672. throw new Exception("预留给打印主要网格的空间太小,请适当调整!");
  673. }
  674. //有效高度中当前页行数
  675. int mRowsInCurPage = 0;
  676. mRowsInCurPage = (int)(validHeight/(float)(this._body.RowHeight));
  677. //如果指定每页行数,则以其为主
  678. if (this.RowsPerPage > 0 && this.RowsPerPage < mRowsInCurPage)
  679. {
  680. mRowsInCurPage = this.RowsPerPage;
  681. }
  682. if (this.IsSubTotalPerPage)
  683. {
  684. mRowsInCurPage--;
  685. }
  686. //TimeDef.End();
  687. //************以Body为主************
  688. //TimeDef.Start();
  689. string[,] mArrGridText; //保留当前页文本,用于页小计
  690. GoldPrinter.Body mbody;
  691. //如果指定每页行数,则以其为主
  692. if (this.RowsPerPage > 0 && this.RowsPerPage < mRowsInCurPage)
  693. {
  694. mbody = new Body(mRowsInCurPage,this._body.Cols);
  695. }
  696. else
  697. {
  698. //否则自适应
  699. if (mRowsInCurPage > (this._body.Rows - this.mCurrentRowIndex))
  700. {
  701. mRowsInCurPage = this._body.Rows - this.mCurrentRowIndex;
  702. }
  703. mbody = new Body(mRowsInCurPage,this._body.Cols);
  704. }
  705. //存当前页的二维文本
  706. mArrGridText = new string[mRowsInCurPage,this._body.Cols];
  707. for(int i = 0 ; i < mRowsInCurPage && mCurrentRowIndex < this._body.Rows ; i++)
  708. {
  709. for(int j = 0 ; j < this._body.Cols ; j++)
  710. {
  711. mArrGridText[i,j] = this._body.GetText(mCurrentRowIndex,j);
  712. }
  713. mCurrentRowIndex++;
  714. }
  715. mbody.GridText = mArrGridText;
  716. mbody.ColsAlignString = this._body.ColsAlignString;
  717. mbody.ColsWidth = this._body.ColsWidth;
  718. mbody.IsAverageColsWidth = this._body.IsAverageColsWidth;
  719. mbody.Font = (Font)(this._body.Font.Clone());
  720. //TimeDef.End();
  721. //TimeDef.Start();
  722. OutObject(mbody);
  723. //TimeDef.End();
  724. //mArrGridText = null;
  725. //判断是否要分页,只要数据网格行数据大于数据网格行指针,则还有下一页
  726. if (mCurrentRowIndex < this._body.Rows)
  727. {
  728. blnHasMorePage = true;
  729. }
  730.             
  731. #region 打印每页小计,只需要将当前数组用循环累计就OK了,这段程序应专门重构为一个函数,读者可以自己试一试
  732.            
  733. if (_isSubTotalPerPage && _subTotalColsList != "")
  734. {
  735. try
  736. {
  737. GoldPrinter.MultiHeader mhSubTotal = new MultiHeader(1,this._body.Cols);
  738. mhSubTotal.ColsWidth = this._body.ColsWidth;
  739. mhSubTotal.Graphics = g;
  740. mhSubTotal.PrintDocument = this.mPrintDocument;
  741. mhSubTotal.Sewing = this._sewing;
  742. mhSubTotal.Rectangle = new Rectangle(X,Y,Width,mhSubTotal.Height);
  743. //循环
  744. //....
  745. mhSubTotal.SetText(0,0,"本页小计");
  746. mhSubTotal.SetText(0,1,"本页小计");
  747. string[] marrSubTotalCol = this._subTotalColsList.Split(';');
  748. Double mdblSubTotal = 0f;
  749. int mintCol = 0;
  750. for(int i = 0 ; i < marrSubTotalCol.Length ; i ++)
  751. {
  752. mintCol = int.Parse(marrSubTotalCol[i]);
  753. for(int j = 0 ; j < mArrGridText.GetLength(0) ; j++)
  754. {
  755. mdblSubTotal += Double.Parse(mArrGridText[j,mintCol]);
  756. }
  757. mhSubTotal.SetText(0,mintCol,mdblSubTotal.ToString());
  758. mdblSubTotal = 0; //网友“有你一生”发现此bug,要求清零
  759. }
  760. mhSubTotal.Draw();
  761. Y += mhSubTotal.Height;
  762. }
  763. catch
  764. {
  765. }
  766. }
  767.             
  768. #endregion
  769.             
  770. #endregion 
  771. if ((_footer != null || _bottom != null) && (mCurrentPageIndex == 1 ||  (_top != null && _top.IsDrawAllPage) || (_header != null && _header.IsDrawAllPage)))
  772. {
  773. Y += CON_SPACE_BODY_FOOTER; //网格与页底距离
  774. }
  775. //打印页脚与最底
  776. if (_footer != null)
  777. {
  778. //最后一页必打
  779. if (blnHasMorePage == false || _footer.IsDrawAllPage)
  780. {
  781. //如果每页都打印,对_footer分页失去了意义
  782. if (_footer.IsDrawAllPage)
  783. {
  784. OutObject(_footer);
  785. }
  786. else
  787. {
  788. //不是每都打,但是最后一页必打_footer,这时要做分页处理
  789. //与Body同样的处理
  790. //...
  791. }
  792.                     
  793. }
  794. }
  795. if (_bottom != null)
  796. {
  797. if (blnHasMorePage == false || _bottom.IsDrawAllPage)
  798. {
  799. if (_bottom.IsDrawAllPage)
  800. {
  801. OutObject(_bottom);
  802. }
  803. else
  804. {
  805. //计算有效高度
  806. validHeight = mPrinter.PrinterMargins.Height - (Y - mPrinter.PrinterMargins.Top);
  807. if (validHeight < _bottom.Height)
  808. {
  809. blnHasMorePage = true;
  810. }
  811. else
  812. {
  813. OutObject(_bottom);
  814. }
  815. }
  816. }
  817. }
  818.             
  819. //画边框
  820. DrawBorder(g,this._multiHeader,mbody);
  821. mbody.Dispose();
  822. mbody = null;
  823. return blnHasMorePage;
  824. }
  825. #endregion
  826. /// <summary>
  827. /// 画打印区域
  828. /// </summary>
  829. private void DrawPrinterMargins(Printer printer)
  830. {
  831. if (this.IsPrinterMargins)
  832. {
  833. printer.DrawPrinterMargins();
  834. }
  835. }
  836. /// <summary>
  837. /// 画装订线
  838. /// </summary>
  839. private void DrawSewing(Printer printer)
  840. {
  841. #region 实现...
  842. if (this.IsSewingLine && this.Sewing.Margin > 0)
  843. {
  844. //对象的线长小于0则自动设置
  845. if (this.Sewing.LineLen <= 0)
  846. {
  847. if (this.Sewing.SewingDirection == SewingDirectionFlag.Left)
  848. {
  849. this.Sewing.LineLen = printer.PageHeight;
  850. }
  851. else if (this.Sewing.SewingDirection == SewingDirectionFlag.Top)
  852. {
  853. this.Sewing.LineLen = printer.PageWidth;
  854. }
  855. }
  856. printer.Sewing = this.Sewing;
  857. printer.DrawSewing();
  858. }
  859. #endregion
  860. }
  861. /// <summary>
  862. /// 画边框
  863. /// </summary>
  864. private void DrawBorder(Graphics g,MultiHeader multiHeader,Body body)
  865. {
  866. #region 实现...
  867. //网格边框矩阵
  868. Rectangle mrecGridBorder;
  869. int x,y,width,height;
  870. width = body.Rectangle.Width;
  871. height = body.Rectangle.Height;
  872. if (multiHeader != null)
  873. {
  874. x = multiHeader.Rectangle.X;
  875. y = multiHeader.Rectangle.Y;
  876. height += multiHeader.Rectangle.Height;
  877. }
  878. else
  879. {
  880. x = body.Rectangle.X;
  881. y = body.Rectangle.Y;
  882. }
  883. if (this.IsSubTotalPerPage)
  884. {
  885. GoldPrinter.MultiHeader m = new MultiHeader(1,1);
  886. height += m.RowHeight;
  887. m = null;
  888. }
  889. mrecGridBorder = new Rectangle(x,y,width,height);
  890. Pen pen = new Pen(Color.Black,1);
  891. GoldPrinter.DrawRectangle dr = new DrawRectangle();
  892. dr.Graphics = g;
  893. dr.Rectangle = mrecGridBorder;
  894. dr.Pen = pen;
  895. switch (GridBorder)
  896. {
  897. case GridBorderFlag.Single:
  898. dr.Draw();
  899. break;
  900. case GridBorderFlag.SingleBold:
  901. dr.Pen.Width = 2;
  902. dr.Draw();
  903. if (multiHeader != null)
  904. {
  905. dr.Rectangle = body.Rectangle;
  906. dr.DrawTopLine();
  907. }
  908. break;
  909. case GridBorderFlag.Double:
  910. dr.Draw();
  911. mrecGridBorder = new Rectangle(x-2,y-2,width+4,height+4);
  912. dr.Rectangle = mrecGridBorder;
  913. dr.Draw();
  914. break;
  915. case GridBorderFlag.DoubleBold:
  916. dr.Draw();
  917. mrecGridBorder = new Rectangle(x-2,y-2,width+4,height+4);
  918. dr.Rectangle = mrecGridBorder;
  919. dr.Pen.Width = 2;
  920. dr.Draw();
  921. break;
  922. }
  923. #endregion
  924. }
  925. /// <summary>
  926. /// 加上装订的非打印区域,打印对象整体移动
  927. /// </summary>
  928. private void AddSewingNonePrintArea()
  929. {
  930. if (this.Sewing.SewingDirection == SewingDirectionFlag.Left)
  931. {
  932. this.mPrinterMargins.Left += this.Sewing.Margin;
  933. this.mPrinterMargins.Width -= this.Sewing.Margin;
  934. }
  935. else if (this.Sewing.SewingDirection == SewingDirectionFlag.Top)
  936. {
  937. this.mPrinterMargins.Top += this.Sewing.Margin;
  938. this.mPrinterMargins.Height -= this.Sewing.Margin;
  939. }
  940. private void WriteMetricsToConsole(PrintPageEventArgs ev)
  941. {
  942. #region 打印相关信息
  943. Graphics g = ev.Graphics;
  944. Console.WriteLine ("*****Information about the printer*****");
  945. Console.WriteLine("纸张的大小  ev.PageSettings.PaperSize:" + ev.PageSettings.PaperSize);
  946. Console.WriteLine("打印分辨率  ev.PageSettings.PrinterResolution:" + ev.PageSettings.PrinterResolution);
  947. Console.WriteLine("旋转的角度  ev.PageSettings.PrinterSettings.LandscapeAngle" + ev.PageSettings.PrinterSettings.LandscapeAngle);
  948. Console.WriteLine("");
  949. Console.WriteLine ("*****Information about the page*****");
  950. Console.WriteLine("页面的大小  ev.PageSettings.Bounds:" + ev.PageSettings.Bounds); 
  951. Console.WriteLine("页面(同上)  ev.PageBounds:" + ev.PageBounds); 
  952. Console.WriteLine("页面的边距    ev.PageSettings.Margins.:" + ev.PageSettings.Margins); 
  953. Console.WriteLine("页面的边距    ev.MarginBounds:" + ev.MarginBounds); 
  954. Console.WriteLine("水平分辨率    ev.Graphics.DpiX:" + ev.Graphics.DpiX ); 
  955. Console.WriteLine("垂直分辨率    ev.Graphics.DpiY:" + ev.Graphics.DpiY ); 
  956. ev.Graphics.SetClip(ev.PageBounds);
  957. Console.WriteLine("ev.Graphics.VisibleClipBounds:" + ev.Graphics.VisibleClipBounds);
  958. SizeF drawingSurfaceSize = new SizeF(
  959. ev.Graphics.VisibleClipBounds.Width * ev.Graphics.DpiX/100,
  960. ev.Graphics.VisibleClipBounds.Height * ev.Graphics.DpiY/100);
  961. Console.WriteLine("drawing Surface Size in Pixels" + drawingSurfaceSize);
  962. #endregion
  963. }
  964. }//End class
  965. }//End Namespace