在WEB系统中,打印的确是比较烦人的问题,如果我们能制作一个属于自己的自定义的打印插件,那么我们在后续自定义打印的时候能随心所欲的控制打印,这样的效果对于程序员来说是非常开心的一件事件,本文将自己开发编写的C# 制作的HTML打印插件分享出来,让有同样需求的朋友提供一个参考;此插件是基于Microsoft .NET Framework 2.0 开发的,缺点是每台客户端在安装插件时,必须要安装Microsoft .NET Framework 2.0 ;本插件能实现 页眉、页脚、表头、标题、表尾的分页打印;支持纸张类型、自动补充空行等功能;由于技术有限,肯定有很多不足的地方,请批评指正!
由于本打印插件是基于我们开发平台的报表基础来开发设计的,所以打印控件的原理:通过JS将页面表格数据生成固定格式的XML字符串(图片通过64base图片格式)传送给打印插件,有打印插件自主绘图生成打印页面。E_Print插件可以在WEB或WinForm中使用:
打印插件完整源码:E_Print.rar (包含插件源码、打包程序、winform调试DEMO)
下面贴出源码:(在源码中有详细的注释说明)
1、PrintControl 打印插件类
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Drawing; 5 using System.Data; 6 using System.Text; 7 using System.Windows.Forms; 8 using System.Runtime.InteropServices; 9 using System.Drawing.Printing; 10 using System.Xml; 11 using System.Security; 12 using System.Drawing.Drawing2D; 13 using System.Drawing.Text; 14 using System.Text.RegularExpressions; 15 16 namespace E_Print 17 { 18 /// <summary> 19 /// 打印控件 20 /// 实现IObjectSafety接口 21 /// 网页上所有所使用到的GUID 通过Guid工具生成的唯一编码 22 /// 74D1ED1D-B1A7-4039-A060-6F544FBE99EC 编码以后不允许修改 23 /// </summary> 24 [Guid("74D1ED1D-B1A7-4039-A060-6F544FBE99EC"), ProgId("EReportPrint"), ComVisible(true)] 25 public partial class PrintControl : UserControl, IObjectSafety 26 { 27 #region 私有变量 28 29 #region 通用参数 30 31 /// <summary> 32 /// 缩放比例 33 /// </summary> 34 private float Zoom = 1; 35 36 /// <summary> 37 /// 网页高度 像素 px 38 /// </summary> 39 private float HtmlHeight = 0; 40 41 /// <summary> 42 /// 网页宽度 像素 px 43 /// </summary> 44 private float HtmlWidth = 0; 45 46 /// <summary> 47 /// 报表区域矩形 48 /// </summary> 49 private RectangleF TableRect = new RectangleF(); 50 51 /// <summary> 52 /// 报表绘制实例 53 /// </summary> 54 private ReportDraw RptDraw = new ReportDraw(); 55 56 #endregion 57 58 #region 页边距 59 60 /// <summary> 61 /// 左边距 62 /// 毫米 mm(一位小数) 63 /// </summary> 64 private float _marginLeft = 9.9f; 65 66 /// <summary> 67 /// 右边距 68 /// </summary> 69 private float _marginRight = 9.9f; 70 71 /// <summary> 72 /// 上边距 73 /// </summary> 74 private float _marginTop = 9.9f; 75 76 /// <summary> 77 /// 下边距 78 /// </summary> 79 private float _marginBottom = 9.9f; 80 81 #endregion 82 83 #region 版型方向 84 85 /// <summary> 86 /// 版型方向 Landscape: true 横向;false 纵向 87 /// </summary> 88 private bool _landscape = false; 89 90 #endregion 91 92 #region 纸型大小 93 94 /// <summary> 95 /// 纸张类型 96 /// </summary> 97 private string _paperName = "A4"; 98 99 /// <summary> 100 /// 纸张宽度 101 /// </summary> 102 private int _paperWidth = 210; // 毫米 103 104 /// <summary> 105 /// 纸张高度 106 /// </summary> 107 private int _paperHeight = 297; // 毫米 108 109 #endregion 110 111 #region 打印参数 112 113 /// <summary> 114 /// 自适应纸张大小方法 115 /// null: 无 116 /// row: 横向 117 /// col: 纵向 118 /// </summary> 119 private string _zoomType = "null"; 120 121 /// <summary> 122 /// 是否每页打印标题 123 /// </summary> 124 private bool _isTblTitleAllPage = false; 125 126 /// <summary> 127 /// 是否每页打印表头 128 /// </summary> 129 private bool _isTblHeadAllPage = false; 130 131 /// <summary> 132 /// 是否每页打印表尾 133 /// </summary> 134 private bool _isTblFootAllPage = false; 135 136 /// <summary> 137 /// 最后一页自动补行 138 /// </summary> 139 private bool _isAutoFillRow = false; 140 141 /// <summary> 142 /// 字符溢出是否换行缩小处理方式 143 /// </summary> 144 private bool _isOverFlow = false; 145 146 /// <summary> 147 /// 打印数据 148 /// </summary> 149 private string _dataXml = ""; 150 151 #endregion 152 153 #region 页眉参数 154 155 /// <summary> 156 /// 页眉--绘制页眉 157 /// </summary> 158 private bool _headDraw = false; 159 160 /// <summary> 161 /// 页眉--高度 毫米 162 /// 默认 10 刚好 163 /// </summary> 164 private float _headHeight = 10.0f; 165 166 /// <summary> 167 /// 页眉--左侧文字 168 /// </summary> 169 private string _headLeft = ""; 170 171 /// <summary> 172 /// 页眉--中间文字 173 /// </summary> 174 private string _headCenter = ""; 175 176 /// <summary> 177 /// 页眉--右侧文字 178 /// </summary> 179 private string _headRight = ""; 180 181 /// <summary> 182 /// 页眉--字体名称 183 /// </summary> 184 private string _headFontName = "宋体"; 185 186 /// <summary> 187 /// 页眉--字体大小 188 /// </summary> 189 private string _headFontSize = "9pt"; 190 191 /// <summary> 192 /// 页眉--字体颜色 193 /// </summary> 194 private string _headFontColor = "Black"; 195 196 /// <summary> 197 /// 页眉--字体--粗体 198 /// </summary> 199 private bool _headFontBold = false; 200 201 /// <summary> 202 /// 页眉--字体--斜体 203 /// </summary> 204 private bool _headFontItalic = false; 205 206 /// <summary> 207 /// 页眉--字体--删除线 208 /// </summary> 209 private bool _headFontStrikeout = false; 210 211 /// <summary> 212 /// 页眉--字体--下划线 213 /// </summary> 214 private bool _headFontUnderline = false; 215 216 /// <summary> 217 /// 页眉--绘制分隔线 218 /// </summary> 219 private bool _headLineDraw = false; 220 221 /// <summary> 222 /// 页眉--分隔线宽度 223 /// </summary> 224 private float _headLineWidth = 1.0f; 225 226 /// <summary> 227 /// 页眉--分隔线线型 228 /// </summary> 229 private string _headLineDash = "solid"; 230 231 /// <summary> 232 /// 页眉--分隔线颜色 233 /// </summary> 234 private string _headLineColor = "Black"; 235 236 #endregion 237 238 #region 页脚参数 239 240 /// <summary> 241 /// 页脚--绘制页脚 242 /// </summary> 243 private bool _footDraw = false; 244 245 /// <summary> 246 /// 页脚--高度 毫米 247 /// </summary> 248 private float _footHeight = 10.0f; 249 250 /// <summary> 251 /// 页脚--左侧文字 252 /// </summary> 253 private string _footLeft = ""; 254 255 /// <summary> 256 /// 页脚--中间文字 257 /// </summary> 258 private string _footCenter = ""; 259 260 /// <summary> 261 /// 页脚--右侧文字 262 /// </summary> 263 private string _footRight = ""; 264 265 /// <summary> 266 /// 页脚--字体名称 267 /// </summary> 268 private string _footFontName = "宋体"; 269 270 /// <summary> 271 /// 页脚--字体大小 272 /// </summary> 273 private string _footFontSize = "9pt"; 274 275 /// <summary> 276 /// 页脚--字体颜色 277 /// </summary> 278 private string _footFontColor = "Black"; 279 280 /// <summary> 281 /// 页脚--字体--粗体 282 /// </summary> 283 private bool _footFontBold = false; 284 285 /// <summary> 286 /// 页脚--字体--斜体 287 /// </summary> 288 private bool _footFontItalic = false; 289 290 /// <summary> 291 /// 页脚--字体--删除线 292 /// </summary> 293 private bool _footFontStrikeout = false; 294 295 /// <summary> 296 /// 页脚--字体--下划线 297 /// </summary> 298 private bool _footFontUnderline = false; 299 300 /// <summary> 301 /// 页脚--绘制分隔线 302 /// </summary> 303 private bool _footLineDraw = false; 304 305 /// <summary> 306 /// 页脚--分隔线宽度 307 /// </summary> 308 private float _footLineWidth = 1.0f; 309 310 /// <summary> 311 /// 页脚--分隔线线型 312 /// </summary> 313 private string _footLineDash = "solid"; 314 315 /// <summary> 316 /// 页脚--分隔线颜色 317 /// </summary> 318 private string _footLineColor = "Black"; 319 320 #endregion 321 322 #endregion 323 324 #region 构造方法 325 326 /// <summary> 327 /// 打印控件构造函数 328 /// </summary> 329 public PrintControl() 330 { 331 InitializeComponent(); 332 Init_PageSetting(); 333 } 334 335 #endregion 336 337 #region 接口实现 338 339 private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}"; 340 private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}"; 341 private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}"; 342 private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}"; 343 private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}"; 344 345 private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001; 346 private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002; 347 private const int S_OK = 0; 348 private const int E_FAIL = unchecked((int)0x80004005); 349 private const int E_NOINTERFACE = unchecked((int)0x80004002); 350 351 private bool _fSafeForScripting = true; 352 private bool _fSafeForInitializing = true; 353 354 public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions) 355 { 356 int Rslt = E_FAIL; 357 358 string strGUID = riid.ToString("B"); 359 pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA; 360 switch (strGUID) 361 { 362 case _IID_IDispatch: 363 case _IID_IDispatchEx: 364 Rslt = S_OK; 365 pdwEnabledOptions = 0; 366 if (_fSafeForScripting == true) 367 pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER; 368 break; 369 case _IID_IPersistStorage: 370 case _IID_IPersistStream: 371 case _IID_IPersistPropertyBag: 372 Rslt = S_OK; 373 pdwEnabledOptions = 0; 374 if (_fSafeForInitializing == true) 375 pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA; 376 break; 377 default: 378 Rslt = E_NOINTERFACE; 379 break; 380 } 381 382 return Rslt; 383 } 384 385 public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions) 386 { 387 int Rslt = E_FAIL; 388 string strGUID = riid.ToString("B"); 389 switch (strGUID) 390 { 391 case _IID_IDispatch: 392 case _IID_IDispatchEx: 393 if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) && (_fSafeForScripting == true)) 394 Rslt = S_OK; 395 break; 396 case _IID_IPersistStorage: 397 case _IID_IPersistStream: 398 case _IID_IPersistPropertyBag: 399 if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) && (_fSafeForInitializing == true)) 400 Rslt = S_OK; 401 break; 402 default: 403 Rslt = E_NOINTERFACE; 404 break; 405 } 406 407 return Rslt; 408 } 409 410 #endregion 411 412 #region 属性方法 413 414 #region 页边距 415 416 /// <summary> 417 /// 获取--设置--左边距 418 /// 计量单位 毫米(mm) 419 /// </summary> 420 public float MARGINLEFT 421 { 422 get { return _marginLeft; } 423 set { _marginLeft = value; } 424 } 425 426 /// <summary> 427 /// 获取--设置--右边距 428 /// 计量单位 毫米(mm) 429 /// </summary> 430 public float MARGINRIGHT 431 { 432 get { return _marginRight; } 433 set { _marginRight = value; } 434 } 435 436 /// <summary> 437 /// 获取--设置--上边距 438 /// 计量单位 毫米(mm) 439 /// </summary> 440 public float MARGINTOP 441 { 442 get { return _marginTop; } 443 set { _marginTop = value; } 444 } 445 446 /// <summary> 447 /// 获取--设置--下边距 448 /// 计量单位 毫米(mm) 449 /// </summary> 450 public float MARGINBOTTOM 451 { 452 get { return _marginBottom; } 453 set { _marginBottom = value; } 454 } 455 456 #endregion 457 458 #region 版型方向 459 460 /// <summary> 461 /// 获取--设置--版型方向 462 /// Landscape: true 横向; false 纵向 463 /// </summary> 464 public bool LANDSCAPE 465 { 466 get { return _landscape; } 467 set { _landscape = value; } 468 } 469 470 #endregion 471 472 #region 纸张属性 473 474 /// <summary> 475 /// 获取--设置--纸张类型 476 /// </summary> 477 public string PAPERNAME 478 { 479 get { return _paperName; } 480 set { _paperName = value; } 481 } 482 483 /// <summary> 484 /// 获取--设置--纸张高度 485 /// 计量单位 毫米(mm) 486 /// </summary> 487 public int PAPERHEIGHT 488 { 489 get { return _paperHeight; } 490 set { _paperHeight = value; } 491 } 492 493 /// <summary> 494 /// 获取--设置--纸张宽度 495 /// 计量单位 毫米(mm) 496 /// </summary> 497 public int PAPERWIDTH 498 { 499 get { return _paperWidth; } 500 set { _paperWidth = value; } 501 } 502 503 #endregion 504 505 #region 页眉参数 506 507 /// <summary> 508 /// 获取--设置--页眉是否绘制 509 /// </summary> 510 public bool HEADDRAW 511 { 512 get { return _headDraw; } 513 set { _headDraw = value; } 514 } 515 516 /// <summary> 517 /// 获取--设置--页眉高度 518 /// 单位:毫米整数类型 519 /// </summary> 520 public float HEADHEIGHT 521 { 522 get { return _headHeight; } 523 set { _headHeight = value; } 524 } 525 526 /// <summary> 527 /// 获取--设置--页眉左侧文字 528 /// </summary> 529 public string HEADLEFT 530 { 531 get { return _headLeft; } 532 set { _headLeft = value; } 533 } 534 535 /// <summary> 536 /// 获取--设置--页眉中间文字 537 /// </summary> 538 public string HEADCENTER 539 { 540 get { return _headCenter; } 541 set { _headCenter = value; } 542 } 543 544 /// <summary> 545 /// 获取--设置--页眉右侧文字 546 /// </summary> 547 public string HEADRIGHT 548 { 549 get { return _headRight; } 550 set { _headRight = value; } 551 } 552 553 /// <summary> 554 /// 获取--设置--页眉字体名称 555 /// </summary> 556 public string HEADFONTNAME 557 { 558 get { return _headFontName; } 559 set { _headFontName = value; } 560 } 561 562 /// <summary> 563 /// 获取--设置--页眉字体大小 564 /// </summary> 565 public string HEADFONTSIZE 566 { 567 get { return _headFontSize; } 568 set { _headFontSize = value; } 569 } 570 571 /// <summary> 572 /// 获取--设置--页眉字体颜色 573 /// </summary> 574 public string HEADFONTCOLOR 575 { 576 get { return _headFontColor; } 577 set { _headFontColor = value; } 578 } 579 580 /// <summary> 581 /// 获取--设置--页眉字体--粗体 582 /// </summary> 583 public bool HEADFONTBOLD 584 { 585 get { return _headFontBold; } 586 set { _headFontBold = value; } 587 } 588 589 /// <summary> 590 /// 获取--设置--页眉字体--斜体 591 /// </summary> 592 public bool HEADFONTITALIC 593 { 594 get { return _headFontItalic; } 595 set { _headFontItalic = value; } 596 } 597 598 /// <summary> 599 /// 获取--设置--页眉字体--删除线 600 /// </summary> 601 public bool HEADFONTSTRIKEOUT 602 { 603 get { return _headFontStrikeout; } 604 set { _headFontStrikeout = value; } 605 } 606 607 /// <summary> 608 /// 获取--设置--页眉字体--下划线 609 /// </summary> 610 public bool HEADFONTUNDERLINE 611 { 612 get { return _headFontUnderline; } 613 set { _headFontUnderline = value; } 614 } 615 616 /// <summary> 617 /// 获取--设置--是否绘制分割线 618 /// </summary> 619 public bool HEADLINEDRAW 620 { 621 get { return _headLineDraw; } 622 set { _headLineDraw = value; } 623 } 624 625 /// <summary> 626 /// 获取--设置--页眉分隔线宽度 627 /// </summary> 628 public float HEADLINEWIDTH 629 { 630 get { return _headLineWidth; } 631 set { _headLineWidth = value; } 632 } 633 634 /// <summary> 635 /// 获取--设置--页眉分隔线线型 636 /// </summary> 637 public string HEADLINEDASH 638 { 639 get { return _headLineDash; } 640 set { _headLineDash = value; } 641 } 642 643 /// <summary> 644 /// 获取--设置--页眉分隔线颜色 645 /// </summary> 646 public string HEADLINECOLOR 647 { 648 get { return _headLineColor; } 649 set { _headLineColor = value; } 650 } 651 652 #endregion 653 654 #region 页脚参数 655 656 /// <summary> 657 /// 获取--设置--页脚是否绘制 658 /// </summary> 659 public bool FOOTDRAW 660 { 661 get { return _footDraw; } 662 set { _footDraw = value; } 663 } 664 665 /// <summary> 666 /// 获取--设置--页脚高度 667 /// 单位:毫米整数类型 668 /// </summary> 669 public float FOOTHEIGHT 670 { 671 get { return _footHeight; } 672 set { _footHeight = value; } 673 } 674 675 /// <summary> 676 /// 获取--设置--页脚左侧文字 677 /// </summary> 678 public string FOOTLEFT 679 { 680 get { return _footLeft; } 681 set { _footLeft = value; } 682 } 683 684 /// <summary> 685 /// 获取--设置--页脚中间文字 686 /// </summary> 687 public string FOOTCENTER 688 { 689 get { return _footCenter; } 690 set { _footCenter = value; } 691 } 692 693 /// <summary> 694 /// 获取--设置--页脚右侧文字 695 /// </summary> 696 public string FOOTRIGHT 697 { 698 get { return _footRight; } 699 set { _footRight = value; } 700 } 701 702 /// <summary> 703 /// 获取--设置--页脚字体名称 704 /// </summary> 705 public string FOOTFONTNAME 706 { 707 get { return _footFontName; } 708 set { _footFontName = value; } 709 } 710 711 /// <summary> 712 /// 获取--设置--页脚字体大小 713 /// </summary> 714 public string FOOTFONTSIZE 715 { 716 get { return _footFontSize; } 717 set { _footFontSize = value; } 718 } 719 720 /// <summary> 721 /// 获取--设置--页脚字体颜色 722 /// </summary> 723 public string FOOTFONTCOLOR 724 { 725 get { return _footFontColor; } 726 set { _footFontColor = value; } 727 } 728 729 /// <summary> 730 /// 获取--设置--页脚字体--粗体 731 /// </summary> 732 public bool FOOTFONTBOLD 733 { 734 get { return _footFontBold; } 735 set { _footFontBold = value; } 736 } 737 738 /// <summary> 739 /// 获取--设置--页脚字体--斜体 740 /// </summary> 741 public bool FOOTFONTITALIC 742 { 743 get { return _footFontItalic; } 744 set { _footFontItalic = value; } 745 } 746 747 /// <summary> 748 /// 获取--设置--页脚字体--删除线 749 /// </summary> 750 public bool FOOTFONTSTRIKEOUT 751 { 752 get { return _footFontStrikeout; } 753 set { _footFontStrikeout = value; } 754 } 755 756 /// <summary> 757 /// 获取--设置--页脚字体--下划线 758 /// </summary> 759 public bool FOOTFONTUNDERLINE 760 { 761 get { return _footFontUnderline; } 762 set { _footFontUnderline = value; } 763 } 764 765 /// <summary> 766 /// 获取--设置--是否绘制分割线 767 /// </summary> 768 public bool FOOTLINEDRAW 769 { 770 get { return _footLineDraw; } 771 set { _footLineDraw = value; } 772 } 773 774 /// <summary> 775 /// 获取--设置--页脚分隔线宽度 776 /// </summary> 777 public float FOOTLINEWIDTH 778 { 779 get { return _footLineWidth; } 780 set { _footLineWidth = value; } 781 } 782 783 /// <summary> 784 /// 获取--设置--页脚分隔线线型 785 /// </summary> 786 public string FOOTLINEDASH 787 { 788 get { return _footLineDash; } 789 set { _footLineDash = value; } 790 } 791 792 /// <summary> 793 /// 获取--设置--页脚分隔线颜色 794 /// </summary> 795 public string FOOTLINECOLOR 796 { 797 get { return _footLineColor; } 798 set { _footLineColor = value; } 799 } 800 801 #endregion 802 803 #region 打印参数 804 805 /// <summary> 806 /// 获取--设置--打印数据 807 /// 前台传入的XML格式的打印数据 808 /// </summary> 809 public string DATAXML 810 { 811 get { return _dataXml; } 812 set { _dataXml = value; } 813 } 814 815 /// <summary> 816 /// 获取--设置--是否每页打印标题 817 /// </summary> 818 public bool ISTBLTITLEALLPAGE 819 { 820 get { return _isTblTitleAllPage; } 821 set { _isTblTitleAllPage = value; } 822 } 823 824 /// <summary> 825 /// 获取--设置--是否每页打印表头 826 /// </summary> 827 public bool ISTBLHEADALLPAGE 828 { 829 get { return _isTblHeadAllPage; } 830 set { _isTblHeadAllPage = value; } 831 } 832 833 /// <summary> 834 /// 获取--设置--是否每页打印表尾 835 /// </summary> 836 public bool ISTBLFOOTALLPAGE 837 { 838 get { return _isTblFootAllPage; } 839 set { _isTblFootAllPage = value; } 840 } 841 842 /// <summary> 843 /// 获取--设置--末页自动补行 844 /// </summary> 845 public bool ISAUTOFILLROW 846 { 847 get { return _isAutoFillRow; } 848 set { _isAutoFillRow = value; } 849 } 850 851 /// <summary> 852 /// 获取--设置--缩放方向 853 /// 参数:以下三种;默认null 854 /// null: 无 855 /// row: 横向 856 /// col: 纵向 857 /// </summary> 858 public string ZOOMTYPE 859 { 860 get { return _zoomType; } 861 set { _zoomType = value; } 862 } 863 864 /// <summary> 865 /// 获取--设置--字符溢出是否缩小换行处理方式 866 /// </summary> 867 public bool ISOVERFLOW 868 { 869 get { return _isOverFlow; } 870 set { _isOverFlow = value; } 871 } 872 873 #endregion 874 875 #region 加载参数 876 877 /// <summary> 878 /// 加载打印参数 879 /// </summary> 880 public void INITPRINTPARAM() 881 { 882 Init_PageSetting(); 883 } 884 885 #endregion 886 887 #endregion 888 889 #region 加载事件 890 891 /// <summary> 892 /// 初始化--页面设置参数 893 /// </summary> 894 private void Init_PageSetting() 895 { 896 this.E_PrintDocument.DefaultPageSettings.Margins.Left = (int)Math.Round(MARGINLEFT * 10); // 左边距 897 this.E_PrintDocument.DefaultPageSettings.Margins.Right = (int)Math.Round(MARGINRIGHT * 10); // 右边距 898 this.E_PrintDocument.DefaultPageSettings.Margins.Top = (int)Math.Round(MARGINTOP * 10); // 上边距 899 this.E_PrintDocument.DefaultPageSettings.Margins.Bottom = (int)Math.Round(MARGINBOTTOM * 10); // 下边距 900 901 this.E_PrintDocument.PrinterSettings.Copies = 1; // 打印份数 902 this.E_PrintDocument.DefaultPageSettings.Landscape = this.LANDSCAPE; // 版型方向 903 PaperSize size = GetPaperSize(PAPERNAME); // 纸张类型 904 if (size != null) 905 this.E_PrintDocument.DefaultPageSettings.PaperSize = size; 906 else 907 this.E_PrintDocument.DefaultPageSettings.PaperSize = new PaperSize(this.PAPERNAME, (int)Math.Round(this.PAPERWIDTH / 25.4 * 100), (int)Math.Round(this.PAPERHEIGHT / 25.4 * 100)); 908 } 909 910 /// <summary> 911 /// 获取--纸张类型 912 /// </summary> 913 /// <param name="paperName">纸张类型名称</param> 914 /// <returns></returns> 915 private PaperSize GetPaperSize(string paperName) 916 { 917 PaperSize paper = null; 918 foreach (PaperSize ps in this.E_PrintDocument.PrinterSettings.PaperSizes) 919 { 920 if (ps.PaperName.ToLower() == paperName.ToLower()) // 检查打印机是否有指定的纸张类型 921 { 922 paper = ps; 923 break; 924 } 925 } 926 return paper; 927 } 928 929 #endregion 930 931 #region 打印事件 932 933 /// <summary> 934 /// 直接打印 935 /// 此处加入了再次调用打印设置界面,因为用户可能需要选择那种打印机 936 /// </summary> 937 /// <returns></returns> 938 public string PRINT() 939 { 940 // 直接打印时,直接调用printDocument的Print()方法 941 // 因为用户可能在打印之前还要再更改打印设置所以需再次显示打印设置对话框 942 if (this.E_PrintDialog.ShowDialog() == DialogResult.OK) 943 { 944 try 945 { 946 this.Init_Printer(); 947 this.E_PrintDocument.Print(); 948 } 949 catch (Exception ex) 950 { 951 this.E_PrintDocument.PrintController.OnEndPrint(this.E_PrintDocument, new PrintEventArgs()); 952 return ex.Message.ToString(); 953 } 954 } 955 return ""; 956 } 957 958 /// <summary> 959 /// 打印预览 960 /// 将打印的数据进行预览 961 /// </summary> 962 public string PREVIEW() 963 { 964 try 965 { 966 this.Init_Printer(); 967 this.E_PrintPreviewDialog.ShowDialog(); 968 } 969 catch (Exception ex) 970 { 971 return ex.Message.ToString(); 972 } 973 974 return ""; 975 } 976 977 /// <summary> 978 /// 页面设置 979 /// 设置打印的页面的纸张大小、纸型、页面边距 980 /// </summary> 981 public void PAGESTE() 982 { 983 // 页面设置对话框中使用的是公制长度计量单位 (厘米) 984 // 在.net中采用的是英制的计量单位 (英寸) 985 // 1英寸约等于2.54厘米,1厘米=10毫米 986 // 所以在下面中需要加入转换信息 将对话框中设置的页边距进行转换保存 987 // 设置传入的纸张信息 988 if (this.E_PageSetupDialog.ShowDialog() == DialogResult.OK) // 弹出页面设置对话框 989 { 990 if (System.Globalization.RegionInfo.CurrentRegion.IsMetric) // 转换页边距计量单位 991 this.E_PageSetupDialog.PageSettings.Margins = PrinterUnitConvert.Convert(this.E_PageSetupDialog.PageSettings.Margins, PrinterUnit.Display, PrinterUnit.TenthsOfAMillimeter); 992 this.E_PrintDocument.DefaultPageSettings = this.E_PageSetupDialog.PageSettings; // 更新页面设置参数值 993 994 // 更新参数 995 this.LANDSCAPE = this.E_PrintDocument.DefaultPageSettings.Landscape; // 版型方向 996 this.PAPERNAME = this.E_PrintDocument.DefaultPageSettings.PaperSize.PaperName; // 纸张类型 997 PaperSize tmPSize = this.E_PrintDocument.DefaultPageSettings.PaperSize; // 纸张尺寸 998 this.PAPERWIDTH = (int)Math.Round(tmPSize.Width * 25.4 / 100); // 纸张宽度 999 this.PAPERHEIGHT = (int)Math.Round(tmPSize.Height * 25.4 / 100); // 纸张高度 1000 this.MARGINLEFT = (float)Math.Round(this.E_PrintDocument.DefaultPageSettings.Margins.Left / 10f, 1); // 左边距 1001 this.MARGINRIGHT = (float)Math.Round(this.E_PrintDocument.DefaultPageSettings.Margins.Right / 10f, 1); // 右边距 1002 this.MARGINTOP = (float)Math.Round(this.E_PrintDocument.DefaultPageSettings.Margins.Top / 10f, 1); // 上边距 1003 this.MARGINBOTTOM = (float)Math.Round(this.E_PrintDocument.DefaultPageSettings.Margins.Bottom / 10f, 1); // 下边距 1004 } 1005 } 1006 1007 /// <summary> 1008 /// 打印设置 1009 /// 设置打印机的信息(选择打印机、设置打印份数等信息) 1010 /// </summary> 1011 public void PRINTSET() 1012 { 1013 this.E_PrintDialog.ShowDialog(); 1014 } 1015 1016 #endregion 1017 1018 #region 绘制对象 1019 1020 /// <summary> 1021 /// 打印及打印前初始化数据 1022 /// </summary> 1023 private void Init_Printer() 1024 { 1025 HtmlHeight = 0; // 网页报表高度 1026 HtmlWidth = 0; // 网页报表宽度 1027 CalcTableRect(); // 计算区域矩形 1028 RptDraw = new ReportDraw(); // 报表绘制实例 1029 RptDraw.IsAllPrintTitle = this._isTblTitleAllPage; // 每页打印标题 1030 RptDraw.IsAllPrintHead = this._isTblHeadAllPage; // 每页打印表头 1031 RptDraw.IsAllPrintFoot = this._isTblFootAllPage; // 每页打印表尾 1032 RptDraw.IsAutoFillRow = this._isAutoFillRow; // 末页自动补行 1033 RptDraw.IsOverFlow = this._isOverFlow; // 字符溢出缩小 1034 RptDraw.ReptRect = TableRect; // 赋值报表矩形 1035 if (!ParseXML()) return; // 解析报表数据 1036 CalcReportZoom(); // 计算缩小比例 1037 CalcZoomAllSize(); // 按比计算尺寸 1038 RptDraw.Zoom = this.Zoom; // 赋值缩小比例 1039 RptDraw.CalcPaging(); // 计算打印分页 1040 } 1041 1042 /// <summary> 1043 /// PrintDocument 对象打印绘制事件 1044 /// </summary> 1045 /// <param name="sender"></param> 1046 /// <param name="e"></param> 1047 private void E_PrintDoc_PrintPage(object sender, PrintPageEventArgs e) 1048 { 1049 Graphics g = e.Graphics; 1050 g.Clear(Color.White); 1051 DrawHeader(g); 1052 DrawFooter(g); 1053 if (RptDraw.DrawReport(g)) 1054 e.HasMorePages = true; 1055 else 1056 e.HasMorePages = false; 1057 1058 } 1059 1060 /// <summary> 1061 /// 绘制页眉 1062 /// </summary> 1063 /// <param name="g">绘图对象</param> 1064 private void DrawHeader(Graphics g) 1065 { 1066 // 是否绘制 1067 if (_headDraw) 1068 { 1069 // 页眉实例 1070 PageHeader pgHeader = new PageHeader(); 1071 1072 // 页眉矩形 1073 RectangleF pgHeaderRect = new RectangleF(TableRect.X, // X 坐标 1074 TableRect.Y - mmToPixel(_headHeight), // Y 坐标 1075 TableRect.Width, // W 宽度 1076 mmToPixel(_headHeight) // H 高度 1077 ); 1078 1079 // 页眉赋值 1080 pgHeader.HeadRect = pgHeaderRect; 1081 pgHeader.StrLeft = ReplacePageNum(_headLeft); // 左侧文本 1082 pgHeader.StrCenter = ReplacePageNum(_headCenter); // 中间文本 1083 pgHeader.StrRight = ReplacePageNum(_headRight); // 右侧文本 1084 FontStyle fontStyle = FontStyle.Regular; // 字体样式 1085 if (_headFontBold) fontStyle |= FontStyle.Bold; 1086 if (_headFontItalic) fontStyle |= FontStyle.Italic; 1087 if (_headFontStrikeout) fontStyle |= FontStyle.Strikeout; 1088 if (_headFontUnderline) fontStyle |= FontStyle.Underline; 1089 1090 pgHeader.StrFont = new Font(_headFontName, (float)Convert.ToDouble(_headFontSize.ToLower().Replace("px", "").Replace("pt", "")), fontStyle, GraphicsUnit.Point); 1091 pgHeader.StrColor = (Color)PrintTool.StrToColor(_headFontColor); 1092 if (_headLineDraw) // 绘制分割线 1093 { 1094 pgHeader.LineDraw = _headLineDraw; 1095 pgHeader.LineWidth = _headLineWidth; 1096 pgHeader.LineColor = (Color)PrintTool.StrToColor(_headLineColor); 1097 pgHeader.LineDash = PrintTool.GetDashStyle(_headLineDash); 1098 } 1099 1100 // 页眉绘制 1101 pgHeader.Draw(g); 1102 } 1103 } 1104 1105 /// <summary> 1106 /// 绘制页脚 1107 /// </summary> 1108 /// <param name="g">绘图对象</param> 1109 private void DrawFooter(Graphics g) 1110 { 1111 // 是否绘制 1112 if (_footDraw) 1113 { 1114 // 页脚实例 1115 PageFooter pgFooter = new PageFooter(); 1116 1117 // 页脚矩形 1118 RectangleF pgFooterRect = new RectangleF(TableRect.X, // X 坐标 1119 TableRect.Y + TableRect.Height, // Y 坐标 1120 TableRect.Width, // W 宽度 1121 mmToPixel(_footHeight) // H 高度 1122 ); 1123 // 页脚赋值 1124 pgFooter.FootRect = pgFooterRect; 1125 pgFooter.StrLeft = ReplacePageNum(_footLeft); // 左侧文本 1126 pgFooter.StrCenter = ReplacePageNum(_footCenter); // 中间文本 1127 pgFooter.StrRight = ReplacePageNum(_footRight); // 右侧文本 1128 FontStyle fontStyle = FontStyle.Regular; // 字体样式 1129 if (_footFontBold) fontStyle |= FontStyle.Bold; 1130 if (_footFontItalic) fontStyle |= FontStyle.Italic; 1131 if (_footFontStrikeout) fontStyle |= FontStyle.Strikeout; 1132 if (_footFontUnderline) fontStyle |= FontStyle.Underline; 1133 1134 pgFooter.StrFont = new Font(_footFontName, (float)Convert.ToDouble(_footFontSize.ToLower().Replace("px", "").Replace("pt", "")), fontStyle, GraphicsUnit.Point); 1135 pgFooter.StrColor = (Color)PrintTool.StrToColor(_footFontColor); 1136 if (_footLineDraw) // 绘制分割线 1137 { 1138 pgFooter.LineDraw = _footLineDraw; 1139 pgFooter.LineWidth = _footLineWidth; 1140 pgFooter.LineColor = (Color)PrintTool.StrToColor(_footLineColor); 1141 pgFooter.LineDash = PrintTool.GetDashStyle(_footLineDash); 1142 } 1143 1144 // 页脚绘制 1145 pgFooter.Draw(g); 1146 } 1147 } 1148 1149 #endregion 1150 1151 #region 辅助方法 1152 1153 /// <summary> 1154 /// 毫米 TO 像素 1155 /// </summary> 1156 /// <param name="mmValue">毫米值</param> 1157 /// <returns></returns> 1158 public static float mmToPixel(float mmValue) //mmValue是毫米,1厘米=10毫米 1159 { 1160 return (mmValue / 25.4f * 100f); 1161 } 1162 1163 /// <summary> 1164 /// 替换 当前页码、总共页数两个变量 1165 /// </summary> 1166 /// <param name="str"></param> 1167 /// <returns></returns> 1168 private string ReplacePageNum(string str) 1169 { 1170 string retStr = ""; 1171 if (str == null || str.Trim() == "") 1172 return retStr; 1173 retStr = str; 1174 int t = 0; 1175 while (t >= 0) 1176 { 1177 t = retStr.IndexOf("[curpage]", StringComparison.OrdinalIgnoreCase); 1178 if (t >= 0) 1179 { 1180 retStr = retStr.Substring(0, t) + RptDraw.CurPageNum.ToString() + retStr.Substring(t + "[curpage]".Length); 1181 } 1182 } 1183 1184 t = 0; 1185 while (t >= 0) 1186 { 1187 t = retStr.IndexOf("[allpage]", StringComparison.OrdinalIgnoreCase); 1188 if (t >= 0) 1189 { 1190 retStr = retStr.Substring(0, t) + RptDraw.AllPageNum.ToString() + retStr.Substring(t + "[allpage]".Length); 1191 } 1192 } 1193 return retStr; 1194 } 1195 1196 /// <summary> 1197 /// 解析XML文件 1198 /// </summary> 1199 /// <returns>返回成功与否</returns> 1200 private bool ParseXML() 1201 { 1202 if (this.DATAXML == null || this.DATAXML.Trim() == "") return false; 1203 XmlDataDocument xmlDoc = new XmlDataDocument(); 1204 try 1205 { 1206 xmlDoc.LoadXml(this.DATAXML); 1207 XmlNode rootNode = xmlDoc.DocumentElement; 1208 if (rootNode.ChildNodes.Count == 0) return false; 1209 if (rootNode.ChildNodes[0].Name.ToLower() != "table") return false; 1210 1211 XmlNode tableNode = rootNode.ChildNodes[0]; // 表格节点 1212 HtmlHeight = float.Parse(tableNode.Attributes["height"].Value); 1213 HtmlWidth = float.Parse(tableNode.Attributes["width"].Value); 1214 1215 int tmRowIndex = 0; 1216 foreach (XmlNode trNode in tableNode.ChildNodes) 1217 { 1218 if (trNode.Name.ToLower() != "tr") continue; 1219 1220 // 解析表格行 1221 Row tmRow = new Row(); 1222 tmRow.RowIndex = tmRowIndex; 1223 tmRow.RowHeight = float.Parse(trNode.Attributes["height"].Value); 1224 tmRow.RowType = trNode.Attributes["rowtype"].Value.ToLower(); 1225 1226 // 解析单元格 1227 foreach (XmlNode tdNode in trNode.ChildNodes) 1228 { 1229 Cell tmCell = new Cell(); 1230 1231 #region 合并\坐标\矩形 1232 1233 tmCell.RowSpan = Convert.ToInt32(tdNode.Attributes["rowspan"].Value); 1234 tmCell.ColSpan = Convert.ToInt32(tdNode.Attributes["colspan"].Value); 1235 tmCell.RowIndex = Convert.ToInt32(tdNode.Attributes["r"].Value); 1236 tmCell.ColIndex = Convert.ToInt32(tdNode.Attributes["c"].Value); 1237 tmCell.RectX = float.Parse(tdNode.Attributes["x"].Value); 1238 tmCell.RectY = float.Parse(tdNode.Attributes["y"].Value); 1239 tmCell.RectW = float.Parse(tdNode.Attributes["w"].Value); 1240 tmCell.RectH = float.Parse(tdNode.Attributes["h"].Value); 1241 1242 #endregion 1243 1244 #region 设置单元格字体 1245 1246 FontStyle tmStyle = new FontStyle(); 1247 tmStyle = FontStyle.Regular; 1248 if (tdNode.Attributes["italic"].Value.ToString() == "1") tmStyle |= FontStyle.Italic; 1249 if (tdNode.Attributes["bold"].Value.ToString() == "1") tmStyle |= FontStyle.Bold; 1250 if (tdNode.Attributes["strikeout"].Value.ToString() == "1") tmStyle |= FontStyle.Strikeout; 1251 if (tdNode.Attributes["underline"].Value.ToString() == "1") tmStyle |= FontStyle.Underline; 1252 tmCell.CellFont = new Font(tdNode.Attributes["fontname"].Value, float.Parse(tdNode.Attributes["fontsize"].Value.Replace("pt", "").Replace("px", "")), tmStyle, GraphicsUnit.Point); 1253 tmCell.FontColor = (Color)PrintTool.StrToColor(tdNode.Attributes["fontcolor"].Value); 1254 tmCell.BackColor = (Color)PrintTool.StrToColor(tdNode.Attributes["backcolor"].Value); 1255 1256 StringFormat tmFormat = new StringFormat(); 1257 switch (tdNode.Attributes["align"].Value.ToLower()) // 水平对齐方式 1258 { 1259 case "center": 1260 tmFormat.Alignment = StringAlignment.Center; 1261 break; 1262 case "right": 1263 tmFormat.Alignment = StringAlignment.Far; 1264 break; 1265 default: 1266 tmFormat.Alignment = StringAlignment.Near; 1267 break; 1268 } 1269 switch (tdNode.Attributes["valign"].Value.ToLower()) // 垂直对齐方式 1270 { 1271 case "middle": 1272 tmFormat.LineAlignment = StringAlignment.Center; 1273 break; 1274 case "bottom": 1275 tmFormat.LineAlignment = StringAlignment.Far; 1276 break; 1277 default: 1278 tmFormat.LineAlignment = StringAlignment.Near; 1279 break; 1280 } 1281 tmCell.strFormat = tmFormat; 1282 1283 #endregion 1284 1285 #region 内嵌图片-属性 1286 1287 tmCell.IsImage = tdNode.Attributes["isimage"].Value.ToString() == "1" ? true : false; 1288 if (tmCell.IsImage) 1289 tmCell.ImageUrl = tdNode.Attributes["imageurl"].Value; 1290 #endregion 1291 1292 #region 单元格边框属性 1293 1294 // 左边框线 1295 string tmVal = tdNode.Attributes["leftwidth"].Value; 1296 if (tmVal.IndexOf("px") >= 0) 1297 { 1298 tmCell.LeftBorder = new BorderLine( 1299 float.Parse(tmVal.Replace("px", "")), 1300 (Color)PrintTool.StrToColor(tdNode.Attributes["leftcolor"].Value), 1301 PrintTool.GetDashStyle(tdNode.Attributes["leftdash"].Value) 1302 ); 1303 } 1304 1305 // 上边框线 1306 tmVal = tdNode.Attributes["topwidth"].Value; 1307 if (tmVal.IndexOf("px") >= 0) 1308 { 1309 tmCell.TopBorder = new BorderLine( 1310 float.Parse(tmVal.Replace("px", "")), 1311 (Color)PrintTool.StrToColor(tdNode.Attributes["topcolor"].Value), 1312 PrintTool.GetDashStyle(tdNode.Attributes["topdash"].Value) 1313 ); 1314 1315 } 1316 1317 // 右边框线 1318 tmVal = tdNode.Attributes["rightwidth"].Value; 1319 if (tmVal.IndexOf("px") >= 0) 1320 { 1321 tmCell.RightBorder = new BorderLine( 1322 float.Parse(tmVal.Replace("px", "")), 1323 (Color)PrintTool.StrToColor(tdNode.Attributes["rightcolor"].Value), 1324 PrintTool.GetDashStyle(tdNode.Attributes["rightdash"].Value) 1325 ); 1326 } 1327 1328 // 下边框线 1329 tmVal = tdNode.Attributes["bottomwidth"].Value; 1330 if (tmVal.IndexOf("px") >= 0) 1331 { 1332 tmCell.BottomBorder = new BorderLine( 1333 float.Parse(tmVal.Replace("px", "")), 1334 (Color)PrintTool.StrToColor(tdNode.Attributes["bottomcolor"].Value), 1335 PrintTool.GetDashStyle(tdNode.Attributes["bottomdash"].Value) 1336 ); 1337 } 1338 1339 #endregion 1340 1341 #region 单据格数据数值 1342 1343 tmCell.Value = tdNode.InnerText; 1344 1345 #endregion 1346 1347 // 加入对应的行内 1348 tmRow.RowCells.Add(tmCell); 1349 } 1350 1351 RptDraw.RowsList.Add(tmRow); 1352 1353 tmRowIndex++; 1354 } 1355 } 1356 catch 1357 { 1358 return false; 1359 } 1360 finally 1361 { 1362 xmlDoc = null; 1363 } 1364 1365 return true; 1366 } 1367 1368 /// <summary> 1369 /// 计算报表区域矩形 1370 /// 真实的绘制报表的区域 1371 /// </summary> 1372 private void CalcTableRect() 1373 { 1374 // 重新初始化实例 1375 TableRect = new RectangleF(); 1376 1377 // 左顶点 X坐标 1378 TableRect.X = mmToPixel(_marginLeft); 1379 1380 // 左顶点 Y坐标 1381 TableRect.Y = mmToPixel(_marginTop); 1382 if (_headDraw) // 需要绘制页眉 1383 TableRect.Y += mmToPixel(_headHeight); 1384 1385 // 报表矩形宽度高度 1386 if (this.LANDSCAPE) // 版型方向 横向 1387 { 1388 // 颠倒 宽高 1389 TableRect.Width = mmToPixel((float)_paperHeight - _marginLeft - _marginRight); 1390 TableRect.Height = mmToPixel((float)_paperWidth - _marginTop - _marginBottom); 1391 } 1392 else // 版型方向 纵向 1393 { 1394 TableRect.Width = mmToPixel((float)_paperWidth - _marginLeft - _marginRight); 1395 TableRect.Height = mmToPixel((float)_paperHeight - _marginTop - _marginBottom); 1396 } 1397 1398 // 报表矩形高度缩减 1399 if (_headDraw) // 需要绘制页眉 1400 TableRect.Height -= mmToPixel(_headHeight); 1401 if (_footDraw) // 需要绘制页脚 1402 TableRect.Height -= mmToPixel(_footHeight); 1403 } 1404 1405 /// <summary> 1406 /// 计算缩放比例 1407 /// </summary> 1408 private void CalcReportZoom() 1409 { 1410 if (this.ZOOMTYPE.ToLower() == "row") 1411 { 1412 if (Convert.ToInt32(TableRect.Width) >= HtmlWidth) 1413 this.Zoom = 1; 1414 else 1415 this.Zoom = TableRect.Width / HtmlWidth; 1416 } 1417 else if (this.ZOOMTYPE.ToLower() == "col") 1418 { 1419 if (Convert.ToInt32(TableRect.Height) >= HtmlHeight) 1420 this.Zoom = 1; 1421 else 1422 this.Zoom = TableRect.Height / HtmlHeight; 1423 } 1424 else 1425 { 1426 this.Zoom = 1; 1427 } 1428 } 1429 1430 /// <summary> 1431 /// 转换所有的尺寸 1432 /// 根据缩放比例 1433 /// </summary> 1434 private void CalcZoomAllSize() 1435 { 1436 if (this.Zoom != 1) 1437 { 1438 // 转换HTML 高度宽度 1439 HtmlWidth = HtmlWidth * Zoom; 1440 HtmlHeight = HtmlHeight * Zoom; 1441 1442 // 转换所有行号 1443 foreach (Row zRow in this.RptDraw.RowsList) 1444 { 1445 // 行高缩小 1446 zRow.RowHeight = zRow.RowHeight * Zoom; 1447 1448 // 转换所有单元格 1449 foreach (Cell zCell in zRow.RowCells) 1450 { 1451 zCell.RectX = zCell.RectX * Zoom; 1452 zCell.RectY = zCell.RectY * Zoom; 1453 zCell.RectW = zCell.RectW * Zoom; 1454 zCell.RectH = zCell.RectH * Zoom; 1455 1456 zCell.TopBorder.LineWidth = zCell.TopBorder.LineWidth * Zoom; 1457 zCell.BottomBorder.LineWidth = zCell.BottomBorder.LineWidth * Zoom; 1458 zCell.LeftBorder.LineWidth = zCell.LeftBorder.LineWidth * Zoom; 1459 zCell.RightBorder.LineWidth = zCell.RightBorder.LineWidth * Zoom; 1460 1461 // 字体相应缩小 1462 zCell.CellFont = new Font(zCell.CellFont.Name, zCell.CellFont.Size * Zoom, zCell.CellFont.Style, GraphicsUnit.Point); 1463 1464 } 1465 } 1466 } 1467 } 1468 1469 #endregion 1470 1471 } 1472 }