程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 網頁WEB打印控件制作,網頁web打印控件

網頁WEB打印控件制作,網頁web打印控件

編輯:C#入門知識

網頁WEB打印控件制作,網頁web打印控件


    在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 } View Code

 

2、ReportDraw 打印繪制類

1 using System; 2 using System.Collections.Generic; 3 using System.Drawing; 4 using System.Drawing.Drawing2D; 5 using System.IO; 6 7 namespace E_Print 8 { 9 /// <summary> 10 /// 報表繪制 11 /// </summary> 12 public class ReportDraw 13 { 14 #region 私有成員 15 16 /// <summary> 17 /// 當前頁碼 18 /// </summary> 19 private int _curPageNum; 20 21 /// <summary> 22 /// 總共頁數 23 /// </summary> 24 private int _allPageNum; 25 26 /// <summary> 27 /// 表格矩形 28 /// </summary> 29 private RectangleF _reptRect; 30 31 /// <summary> 32 /// 報表全部行集 33 /// </summary> 34 private List<Row> _rowsList; 35 36 /// <summary> 37 /// 分頁頁面數組 38 /// </summary> 39 private List<PagingItem> _pageList; 40 41 /// <summary> 42 /// 是否每頁打印標題 43 /// </summary> 44 private bool _isAllPrintTitle; 45 46 /// <summary> 47 /// 是否每頁打印表頭 48 /// </summary> 49 private bool _isAllPrintHead; 50 51 /// <summary> 52 /// 是否每頁打印表尾 53 /// </summary> 54 private bool _isAllPrintFoot; 55 56 /// <summary> 57 /// 是否末頁自動補行 58 /// </summary> 59 private bool _isAutoFillRow; 60 61 /// <summary> 62 /// 縮小比例 63 /// </summary> 64 private float _zoom; 65 66 /// <summary> 67 /// 字符溢出處理方式 68 /// </summary> 69 private bool _isOverFlow; 70 71 /// <summary> 72 /// 每頁打印的標題+表頭的高度 73 /// </summary> 74 private float _headPix; 75 76 /// <summary> 77 /// 每頁打印的表尾高度 78 /// </summary> 79 private float _footPix; 80 81 #endregion 82 83 #region 構造方法 84 85 /// <summary> 86 /// 構造函數 87 /// </summary> 88 public ReportDraw() 89 { 90 _curPageNum = 1; 91 _allPageNum = 1; 92 _reptRect = new RectangleF(); 93 _rowsList = new List<Row>(); 94 _pageList = new List<PagingItem>(); 95 96 _isAllPrintTitle = false; 97 _isAllPrintHead = false; 98 _isAllPrintFoot = false; 99 _isAutoFillRow = false; 100 101 _zoom = 1; 102 _isOverFlow = false; 103 _headPix = 0; 104 _footPix = 0; 105 } 106 107 /// <summary> 108 /// 構造函數 109 /// </summary> 110 /// <param name="printTitle">每頁打印標題</param> 111 /// <param name="printHead">每頁打印表頭</param> 112 /// <param name="printFoot">每頁打印表位</param> 113 /// <param name="fillRows">自動補全空行</param> 114 /// <param name="tableRect">報表尺寸矩形</param> 115 /// <param name="overFlow">字符溢出處理</param> 116 public ReportDraw(bool printTitle, bool printHead, bool printFoot, bool fillRows, RectangleF tableRect, bool overFlow) 117 { 118 119 _reptRect = tableRect; 120 _isAllPrintTitle = printTitle; 121 _isAllPrintHead = printHead; 122 _isAllPrintFoot = printFoot; 123 _isAutoFillRow = fillRows; 124 _isOverFlow = overFlow; 125 126 _curPageNum = 1; 127 _allPageNum = 1; 128 _zoom = 1; 129 _rowsList = new List<Row>(); 130 _pageList = new List<PagingItem>(); 131 132 _headPix = 0; 133 _footPix = 0; 134 } 135 136 #endregion 137 138 #region 屬性方法 139 140 /// <summary> 141 /// 獲取--設置--當前頁碼 142 /// </summary> 143 public int CurPageNum 144 { 145 get { return _curPageNum; } 146 set { _curPageNum = value; } 147 } 148 149 /// <summary> 150 /// 獲取--設置--總共頁數 151 /// </summary> 152 public int AllPageNum 153 { 154 get { return _allPageNum; } 155 set { _allPageNum = value; } 156 } 157 158 /// <summary> 159 /// 獲取--設置--表格矩形 160 /// </summary> 161 public RectangleF ReptRect 162 { 163 get { return _reptRect; } 164 set { _reptRect = value; } 165 } 166 167 /// <summary> 168 /// 獲取--設置--報表全部行集 169 /// </summary> 170 public List<Row> RowsList 171 { 172 get { return _rowsList; } 173 set { _rowsList = value; } 174 } 175 176 /// <summary> 177 /// 獲取--設置--分頁頁面數組 178 /// </summary> 179 public List<PagingItem> PageList 180 { 181 get { return _pageList; } 182 set { _pageList = value; } 183 } 184 185 /// <summary> 186 /// 獲取--設置--是否每頁打印標題 187 /// </summary> 188 public bool IsAllPrintTitle 189 { 190 get { return _isAllPrintTitle; } 191 set { _isAllPrintTitle = value; } 192 } 193 194 /// <summary> 195 /// 獲取--設置--是否每頁打印表頭 196 /// </summary> 197 public bool IsAllPrintHead 198 { 199 get { return _isAllPrintHead; } 200 set { _isAllPrintHead = value; } 201 } 202 203 /// <summary> 204 /// 獲取--設置--是否每頁打印表尾 205 /// </summary> 206 public bool IsAllPrintFoot 207 { 208 get { return _isAllPrintFoot; } 209 set { _isAllPrintFoot = value; } 210 } 211 212 /// <summary> 213 /// 獲取--設置--末頁是否自動補行 214 /// </summary> 215 public bool IsAutoFillRow 216 { 217 get { return _isAutoFillRow; } 218 set { _isAutoFillRow = value; } 219 } 220 221 /// <summary> 222 /// 獲取--設置--縮小比例 223 /// </summary> 224 public float Zoom 225 { 226 get { return _zoom; } 227 set { _zoom = value; } 228 } 229 230 /// <summary> 231 /// 獲取--設置--字符溢出處理方式 232 /// </summary> 233 public bool IsOverFlow 234 { 235 get { return _isOverFlow; } 236 set { _isOverFlow = value; } 237 } 238 239 /// <summary> 240 /// 獲取--設置--每頁打印的標題+表頭高度 241 /// </summary> 242 public float HeadPix 243 { 244 get { return _headPix; } 245 set { _headPix = value; } 246 } 247 248 /// <summary> 249 /// 獲取--設置--每頁打印的表尾高度 250 /// </summary> 251 public float FootPix 252 { 253 get { return _footPix; } 254 set { _footPix = value; } 255 } 256 257 #endregion 258 259 #region 計算分頁 260 261 /// <summary> 262 /// 計算分頁 263 /// </summary> 264 public void CalcPaging() 265 { 266 // 分頁實例 267 PagingCalc insCalc = new PagingCalc(); 268 insCalc.TableRect = this.ReptRect; 269 insCalc.RowsList = this.RowsList; 270 insCalc.IsAllPrintTitle = this.IsAllPrintTitle; 271 insCalc.IsAllPrintHead = this.IsAllPrintHead; 272 insCalc.IsAllPrintFoot = this.IsAllPrintFoot; 273 274 // 分頁計算 275 _pageList = insCalc.CalcPages(); 276 this._allPageNum = _pageList.Count; 277 this._curPageNum = 1; 278 279 this._headPix = insCalc.MyHeadPix; 280 this._footPix = insCalc.MyFootPix; 281 } 282 283 #endregion 284 285 #region 繪制方法 286 287 /// <summary> 288 /// 繪制報表 289 /// </summary> 290 /// <param name="g"></param> 291 /// <returns>返回是否結束</returns> 292 public bool DrawReport(Graphics g) 293 { 294 bool isMorePage = false; 295 float offsetX = _reptRect.X; // X 偏移量 296 float offsetY = _reptRect.Y; // Y 偏移量 297 298 bool isCanFillRow = false; // 是否需要補行 299 bool isFillFlag = false; // 是否已經補過 300 int isFillRowNum = 0; // 需要補充幾行 301 302 PagingItem nowPage = GetPageItem(CurPageNum); // 當前頁 303 if (nowPage != null) 304 { 305 #region 判定高度不足是否自動補行 306 307 // 判定補行條件 報表設置了末頁不足自動補行、同時 為最後一頁 308 if (_isAutoFillRow == true && CurPageNum == AllPageNum) 309 { 310 // 判定頁面高度 與 數據高度 311 float N_PageHeith = ReptRect.Height; // 當前頁面高度 312 float N_DataHeith = GetThisPageDataRowsHeight(); // 當前數據高度 313 314 // 補行行高21 315 while ((N_DataHeith + (isFillRowNum + 1) * 21 * Zoom) < N_PageHeith) 316 { 317 isFillRowNum++; 318 } 319 320 if (isFillRowNum > 0) 321 isCanFillRow = true; 322 } 323 324 #endregion 325 326 #region 首先繪制上一頁補充單元格 327 328 if (CurPageNum > 1) 329 { 330 PagingItem prePage = GetPageItem(CurPageNum - 1); // 上一頁 331 if (prePage != null) 332 { 333 foreach (PagingMakeUp tmMk in prePage.MakeupList) 334 { 335 // 繪制補充單元格(上頁中未繪制完成的單元格) 336 DrawTD(g, tmMk.MakeupCell, offsetX, offsetY, true, tmMk.MakeupHeight, false); 337 } 338 } 339 } 340 341 #endregion 342 343 #region 其次繪制當前頁面的單元格 344 345 // 其次繪制當前頁的單元格 346 for (int ii = 0; ii < nowPage.IndexList.Count; ii++) 347 { 348 // 先繪制 TD CELL 單元格 349 Row rowTR = GetRow(nowPage.IndexList[ii]); 350 351 #region 執行補行 352 353 if (isCanFillRow == true && rowTR.RowType.ToLower().Trim() == "f") // 需要補行 行標志為F 表尾前進行補充空行 354 { 355 Row fillRow = new Row(); 356 if (ii == 0) 357 fillRow = rowTR; 358 else 359 fillRow = GetRow(nowPage.IndexList[ii - 1]); 360 if (fillRow != null) // 繪制自動補充的空行單元格 361 { 362 // 開始補充空行 363 for (int fi = 1; fi <= isFillRowNum; fi++) 364 { 365 bool bcFlag = true; 366 // 繪制單元格 367 foreach (Cell fillTdCell in fillRow.RowCells) 368 { 369 if (bcFlag) 370 { 371 // 繪制邊框線(合並單元格的情況才用到) 372 if (fillTdCell.RectX > 0) 373 { 374 DrawLine(g, offsetX, offsetY, offsetX, offsetY + 21.0F * Zoom); // 最左邊豎線 375 DrawLine(g, offsetX, offsetY + 21.0F * Zoom, offsetX + fillTdCell.RectX, offsetY + 21.0F * Zoom); 376 } 377 bcFlag = false; 378 } 379 DrawTD(g, fillTdCell, offsetX, offsetY, false, 0, true); 380 } 381 382 // 再將偏移量+行號 補充的行高全部為21px 383 offsetY += 21 * Zoom; 384 } 385 } 386 387 isFillFlag = true; 388 } 389 390 #endregion 391 392 #region 正常繪制 393 394 foreach (Cell td in rowTR.RowCells) 395 { 396 DrawTD(g, td, offsetX, offsetY, false, 0, false); 397 } 398 399 // 再將偏移量+行號 400 offsetY += rowTR.RowHeight; 401 402 #endregion 403 } 404 405 // 判定是否補過;沒有補充過,則在最後進行補充空行 406 if ((isCanFillRow == true) && (isFillFlag == false) && (nowPage.IndexList.Count > 0)) 407 { 408 Row fillRow = GetRow(nowPage.IndexList[nowPage.IndexList.Count - 1]); 409 if (fillRow != null) // 繪制自動補充的空行單元格 410 { 411 412 // 開始補充空行 413 for (int fi = 1; fi <= isFillRowNum; fi++) 414 { 415 bool newFlag = true; 416 foreach (Cell fillTdCell in fillRow.RowCells) 417 { 418 if (newFlag) 419 { 420 // 繪制邊框線(合並單元格的情況才用到) 421 if (fillTdCell.RectX > 0) 422 { 423 DrawLine(g, offsetX, offsetY, offsetX, offsetY + 21.0F * Zoom); // 最左邊豎線 424 DrawLine(g, offsetX, offsetY + 21.0F * Zoom, offsetX + fillTdCell.RectX, offsetY + 21.0F * Zoom); 425 } 426 newFlag = false; 427 } 428 DrawTD(g, fillTdCell, offsetX, offsetY, false, 0, true); 429 } 430 offsetY += 21 * Zoom; // 再將偏移量+行號 補充的行高全部為21px 431 } 432 } 433 } 434 435 #endregion 436 437 if (CurPageNum < AllPageNum) 438 { 439 isMorePage = true; // 還有下頁 440 CurPageNum++; // 頁碼增加 441 } 442 } 443 return isMorePage; 444 } 445 446 /// <summary> 447 /// 繪制單元格 448 /// </summary> 449 /// <param name="g">繪圖對象</param> 450 /// <param name="tdCell">單元格</param> 451 /// <param name="setX">X偏移量</param> 452 /// <param name="setY">Y坐標值</param> 453 /// <param name="isMakeup">是否補充單元格</param> 454 /// <param name="mkH">補充單元格高度</param> 455 /// <param name="fillCell">自動補行的單元格</param> 456 private void DrawTD(Graphics g, Cell tdCell, float setX, float setY, bool isMakeup, float mkH, bool fillCell) 457 { 458 #region 參數變量 459 460 Pen pen; 461 Brush brush; 462 463 // 獲取單元格繪制坐標矩形信息 464 float tdX = tdCell.RectX + setX; 465 float tdY = setY; 466 float tdW = tdCell.RectW; 467 float tdH = 0; 468 469 if (fillCell) 470 { 471 tdH = 21 * Zoom; // 自動補行的單元格的高度固定為21px 472 } 473 else 474 { 475 if (isMakeup) // 補充單元格 476 { 477 tdH = mkH; 478 tdY = tdY + HeadPix; // 如果是補充單元格,則此單元格的Y坐標:如果每頁打印標題或表頭,則Y坐標 需要下移 HeadPix 479 } 480 else // 實際單元格 481 { 482 tdH = tdCell.RectH; 483 } 484 if (tdCell.RowSpan > 1) // 判定單元格高度是否超過底線 485 { 486 tdH = Calc_CellOverHeight(tdCell, tdY, tdH); 487 } 488 } 489 490 #endregion 491 492 #region 繪制背景 493 494 // 填充顏色 495 brush = new SolidBrush(tdCell.BackColor); 496 g.FillRectangle(brush, tdX + 1.0f * Zoom, tdY + 1.0f * Zoom, tdW - 2.0f * Zoom, tdH - 2.0f * Zoom); 497 498 #endregion 499 500 #region 繪制邊框 501 502 // 左邊框線 503 if (tdCell.LeftBorder.LineWidth > 0) 504 { 505 pen = new Pen(tdCell.LeftBorder.LineColor); 506 pen.DashStyle = tdCell.LeftBorder.LineDash; 507 pen.Width = tdCell.LeftBorder.LineWidth; 508 g.DrawLine(pen, tdX, tdY, tdX, tdY + tdH); 509 } 510 511 // 上邊框線 512 if (tdCell.TopBorder.LineWidth > 0) 513 { 514 pen = new Pen(tdCell.TopBorder.LineColor); 515 pen.DashStyle = tdCell.TopBorder.LineDash; 516 pen.Width = tdCell.TopBorder.LineWidth; 517 g.DrawLine(pen, tdX, tdY, tdX + tdW, tdY); 518 } 519 520 // 右邊框線 521 if (tdCell.RightBorder.LineWidth > 0) 522 { 523 pen = new Pen(tdCell.RightBorder.LineColor); 524 pen.DashStyle = tdCell.RightBorder.LineDash; 525 pen.Width = tdCell.RightBorder.LineWidth; 526 g.DrawLine(pen, tdX + tdW, tdY, tdX + tdW, tdY + tdH); 527 } 528 529 // 下邊框線 530 if (tdCell.BottomBorder.LineWidth > 0) 531 { 532 pen = new Pen(tdCell.BottomBorder.LineColor); 533 pen.DashStyle = tdCell.BottomBorder.LineDash; 534 pen.Width = tdCell.BottomBorder.LineWidth; 535 g.DrawLine(pen, tdX, tdY + tdH, tdX + tdW, tdY + tdH); 536 } 537 538 #endregion 539 540 #region 繪制文字 541 542 if (!fillCell) 543 { 544 RectangleF rect = new RectangleF(tdX, tdY, tdW, tdH); 545 if (tdCell.IsImage) 546 { 547 this.DrawImg(g, rect, tdCell.ImageUrl); 548 } 549 else 550 { 551 brush = new SolidBrush(tdCell.FontColor); 552 this.DrawStr(g, rect, brush, tdCell.CellFont, tdCell.strFormat, tdCell.Value); 553 } 554 } 555 556 #endregion 557 } 558 559 /// <summary> 560 /// 繪制字符串 561 /// 溢出時,換行縮小字符 562 /// 字體縮小到的最小值不得小於 563 /// </summary> 564 /// <param name="g">繪圖對象</param> 565 /// <param name="strRect">文本區域</param> 566 /// <param name="strBrush">文本筆畫</param> 567 /// <param name="strFont">文本字體</param> 568 /// <param name="strFormat">文本格式</param> 569 /// <param name="strValue">文本字符</param> 570 /// <returns></returns> 571 private void DrawStr(Graphics g, RectangleF strRect, Brush strBrush, Font strFont, StringFormat strFormat, string strValue) 572 { 573 // 報表設置:字符溢出不做處理 574 if (!this.IsOverFlow) 575 { 576 g.DrawString(strValue, strFont, strBrush, strRect, strFormat); 577 } 578 else // 需要處理 579 { 580 // 測量字體的寬度和高度 會發現誤差很大,如果一個一個的測量,誤差就實在太大,所以這裡就用簡單的方式來進行處理 581 SizeF sf = g.MeasureString(strValue, strFont); // 此種方式測量誤差很大,如果 582 if (strRect.Width > sf.Width) 583 { 584 g.DrawString(strValue, strFont, strBrush, strRect, strFormat); 585 } 586 else 587 { 588 // 計算換行後字符的全部高度是否滿足 589 int maxLines = 0; // 計算當前字符當前字體最大打印的行數 590 maxLines = (int)Math.Ceiling((double)sf.Width / (double)strRect.Width); 591 if (strRect.Height >= maxLines * sf.Height) 592 { 593 g.DrawString(strValue, strFont, strBrush, strRect, strFormat); 594 } 595 else 596 { 597 float tmScale = strRect.Height / (maxLines * sf.Height); 598 Font tmNewFont = new Font(strFont.Name, strFont.Size * tmScale, strFont.Style, GraphicsUnit.Point); 599 g.DrawString(strValue, tmNewFont, strBrush, strRect, strFormat); 600 } 601 } 602 } 603 604 } 605 606 /// <summary> 607 /// 繪制圖片 608 /// 將Base64圖片流字符串轉換成圖片並進行繪制 609 /// </summary> 610 /// <param name="g"></param> 611 /// <param name="strRect"></param> 612 /// <param name="base64Img"></param> 613 private void DrawImg(Graphics g, RectangleF strRect, string base64Img) 614 { 615 if (base64Img.Trim() == "") return; 616 string imgStr = base64Img.Replace("data:image/gif;base64,", "").Trim(); 617 if (imgStr == "") return; 618 619 // 生成圖片 620 try 621 { 622 MemoryStream stream = new MemoryStream(Convert.FromBase64String(imgStr)); 623 Bitmap picImg = new Bitmap(stream); 624 625 RectangleF imgRectF = new RectangleF(0f, 0f, (float)picImg.Width, (float)picImg.Height); // 原始圖片矩形 626 RectangleF newRectF = new RectangleF(strRect.X + 1f, strRect.Y + 1f, (float)strRect.Width - 2f, (float)strRect.Height - 2f); // 繪制圖片矩形 627 g.DrawImage(picImg, newRectF, imgRectF, GraphicsUnit.Pixel); // 繪制縮放圖片 628 stream.Close(); 629 } 630 catch 631 { 632 return; 633 } 634 } 635 636 /// <summary> 637 /// 繪制線條 638 /// </summary> 639 /// <param name="g">繪圖對象</param> 640 /// <param name="start_X">開始X</param> 641 /// <param name="start_Y">開始Y</param> 642 /// <param name="end_X">結束X</param> 643 /// <param name="end_Y">結束Y</param> 644 private void DrawLine(Graphics g, float start_X, float start_Y, float end_X, float end_Y) 645 { 646 Pen linePen = new Pen(Color.Black, 1.0f); 647 linePen.DashStyle = DashStyle.Solid; 648 g.DrawLine(linePen, start_X, start_Y, end_X, end_Y); 649 } 650 651 private float ChangeUnit(float vSize) 652 { 653 return (vSize * 72f / 96f * 72f / 75f); 654 } 655 656 /// <summary> 657 /// 獲取行對象 658 /// </summary> 659 /// <param name="rowIndex"></param> 660 /// <returns></returns> 661 private Row GetRow(int rowIndex) 662 { 663 foreach (Row retRow in _rowsList) 664 { 665 if (retRow.RowIndex == rowIndex) 666 return retRow; 667 } 668 return null; 669 } 670 671 /// <summary> 672 /// 獲取分頁頁面 673 /// </summary> 674 /// <param name="pNo">頁碼</param> 675 /// <returns></returns> 676 private PagingItem GetPageItem(int pNo) 677 { 678 foreach (PagingItem retPItem in PageList) 679 { 680 if (retPItem.PageNum == pNo) 681 return retPItem; 682 } 683 684 return null; 685 } 686 687 /// <summary> 688 /// 計算繪制高度 689 /// 判定並且計算單元格高度是否超過當前頁面所有行高度的底線 690 /// </summary> 691 /// <param name="mCell">單元格</param> 692 /// <param name="mY">Y 軸坐標值</param> 693 /// <param name="mH">H 當前高度</param> 694 /// <returns></returns> 695 private float Calc_CellOverHeight(Cell mCell, float mY, float mH) 696 { 697 float returnHeight = 0; // 返回高度 698 float tm_AllTrHeight = GetThisPageDataRowsHeight(); // 當前頁面內所有數據行的高度 699 float tm_RealY = 0; // 相對最大Y值 700 float tm_AbsY = 0; // 實際最大Y值 701 float tm_OverPlus = 0; // 單元格剩余高度 702 tm_RealY = mY + mH; // 實際最大Y值 703 if (IsAllPrintFoot) // 每頁打印表尾 704 tm_AbsY = ReptRect.Y + (tm_AllTrHeight - FootPix); // 需要減去表尾高度 705 else 706 tm_AbsY = tm_AllTrHeight + ReptRect.Y; 707 708 if (tm_RealY > tm_AbsY) 709 { 710 returnHeight = tm_AbsY - mY; // 當前頁面實際最大高度-單元格的當前Y坐標值 = 返回單元格在本頁內需要繪制的高度 711 tm_OverPlus = mH - returnHeight; // 當前高度-單元格當前頁面需要繪制的高度=下頁需要繪制的補充高度 712 713 // 將當前單元格添加到後頁需要補充繪制數組中去 714 PagingItem nPageItem = GetPageItem(CurPageNum); 715 PagingMakeUp nMakeUp = new PagingMakeUp(); 716 nMakeUp.MakeupCell = mCell; 717 nMakeUp.MakeupHeight = tm_OverPlus; 718 nPageItem.MakeupList.Add(nMakeUp); 719 } 720 else 721 { 722 returnHeight = mH; 723 } 724 725 return returnHeight; 726 } 727 728 /// <summary> 729 /// 獲取本頁內所有數據行的高度 730 /// </summary> 731 /// <returns></returns> 732 private float GetThisPageDataRowsHeight() 733 { 734 float retHeight = 0; 735 PagingItem oThisPage = GetPageItem(CurPageNum); // 當前頁 736 737 foreach (int oRowIndex in oThisPage.IndexList) 738 { 739 Row oThisRow = GetRow(oRowIndex); 740 retHeight += oThisRow.RowHeight; 741 } 742 743 return retHeight; 744 } 745 746 /// <summary> 747 /// 獲取頁內某一項所屬行的高度 748 /// </summary> 749 /// <param name="itemPage">頁面對象</param> 750 /// <param name="itemIndex">本頁行數組中的某一項的序號</param> 751 /// <returns></returns> 752 private float GetThisPageOneRowHeight(PagingItem itemPage, int itemIndex) 753 { 754 float retHeight = 0; 755 if (itemIndex < itemPage.IndexList.Count && itemIndex >= 0) 756 { 757 Row oThisRow = GetRow(itemPage.IndexList[itemIndex]); 758 retHeight = oThisRow.RowHeight; 759 } 760 return retHeight; 761 } 762 763 #endregion 764 765 } 766 } View Code

3、PagingCalc 分頁計算類

1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 using System.Drawing; 5 6 namespace E_Print 7 { 8 /// <summary> 9 /// 分頁計算 10 /// </summary> 11 public class PagingCalc 12 { 13 #region 私有變量 14 15 /// <summary> 16 /// 表格區域 17 /// </summary> 18 private RectangleF _tableRect; 19 20 /// <summary> 21 /// 報表行集 22 /// </summary> 23 private List<Row> _rowsList; 24 25 /// <summary> 26 /// 是否每頁打印標題 27 /// </summary> 28 private bool _isAllPrintTitle; 29 30 /// <summary> 31 /// 是否每頁打印表頭 32 /// </summary> 33 private bool _isAllPrintHead; 34 35 /// <summary> 36 /// 是否每頁打印表尾 37 /// </summary> 38 private bool _isAllPrintFoot; 39 40 /// <summary> 41 /// 標題行集 42 /// </summary> 43 private List<Row> TitleList; 44 45 /// <summary> 46 /// 表頭前行集 47 /// </summary> 48 private List<Row> HForeList; 49 50 /// <summary> 51 /// 表頭行集 52 /// </summary> 53 private List<Row> HeadList; 54 55 /// <summary> 56 /// 數據行集 57 /// </summary> 58 private List<Row> DataList; 59 60 /// <summary> 61 /// 表尾行集 62 /// </summary> 63 private List<Row> FootList; 64 65 /// <summary> 66 /// 每頁打印標題+表頭高度 67 /// </summary> 68 private float _myHeadPix; 69 70 /// <summary> 71 /// 每頁打印表尾高度 72 /// </summary> 73 private float _myFootPix; 74 75 #endregion 76 77 #region 構造方法 78 79 /// <summary> 80 /// 構造函數 81 /// </summary> 82 public PagingCalc() 83 { 84 _tableRect = new RectangleF(); 85 _rowsList = new List<Row>(); 86 87 _isAllPrintTitle = false; 88 _isAllPrintHead = false; 89 _isAllPrintFoot = false; 90 91 TitleList = new List<Row>(); 92 HForeList = new List<Row>(); 93 HeadList = new List<Row>(); 94 DataList = new List<Row>(); 95 FootList = new List<Row>(); 96 97 _myHeadPix = 0; 98 _myFootPix = 0; 99 } 100 101 #endregion 102 103 #region 屬性方法 104 105 /// <summary> 106 /// 獲取--設置--表格區域 107 /// </summary> 108 public RectangleF TableRect 109 { 110 get { return _tableRect; } 111 set { _tableRect = value; } 112 } 113 114 /// <summary> 115 /// 獲取--設置--表格行集 116 /// </summary> 117 public List<Row> RowsList 118 { 119 get { return _rowsList; } 120 set { _rowsList = value; } 121 } 122 123 /// <summary> 124 /// 獲取--設置--是否每頁打印標題 125 /// </summary> 126 public bool IsAllPrintTitle 127 { 128 get { return _isAllPrintTitle; } 129 set { _isAllPrintTitle = value; } 130 } 131 132 /// <summary> 133 /// 獲取--設置--是否每頁打印表頭 134 /// </summary> 135 public bool IsAllPrintHead 136 { 137 get { return _isAllPrintHead; } 138 set { _isAllPrintHead = value; } 139 } 140 141 /// <summary> 142 /// 獲取--設置--是否每頁打印表尾 143 /// </summary> 144 public bool IsAllPrintFoot 145 { 146 get { return _isAllPrintFoot; } 147 set { _isAllPrintFoot = value; } 148 } 149 150 /// <summary> 151 /// 獲取--設置--每頁打印標題+表頭高度 152 /// </summary> 153 public float MyHeadPix 154 { 155 get { return _myHeadPix; } 156 set { _myHeadPix = value; } 157 } 158 159 /// <summary> 160 /// 獲取--設置--每頁打印表尾巴高度 161 /// </summary> 162 public float MyFootPix 163 { 164 get { return _myFootPix; } 165 set { _myFootPix = value; } 166 } 167 168 #endregion 169 170 #region 計算方法 171 172 /// <summary> 173 /// 分頁計算 174 /// </summary> 175 /// <returns></returns> 176 public List<PagingItem> CalcPages() 177 { 178 List<PagingItem> retPages = new List<PagingItem>(); 179 180 // 無需分頁 181 if (Get_TableAllHeight() <= TableRect.Height) 182 { 183 PagingItem tmItem0 = new PagingItem(); 184 tmItem0.PageNum = 1; 185 for (int y = 0; y < RowsList.Count; y++) 186 { 187 tmItem0.IndexList.Add(y); 188 } 189 retPages.Add(tmItem0); 190 } 191 else // 需要分頁 192 { 193 // 有設置了 每頁打印標題、表頭、表位 其中的任意一個 194 if (Get_IsCusSet_THDF()) // 則執行每頁相對分頁 195 { 196 Paging_Relative(0, ref retPages); 197 198 // 計算每頁打印頭尾高度 199 MyHeadPix = 0; 200 if (IsAllPrintTitle) 201 { 202 MyHeadPix += Get_TableTileHeight(); 203 } 204 205 if (IsAllPrintHead) 206 { 207 MyHeadPix += Get_TableHeadHeight(); 208 } 209 210 if (IsAllPrintFoot) 211 { 212 MyFootPix = Get_TableFootHeight(); 213 } 214 } 215 else // 執行直接數據分頁 216 { 217 Paging_Direct(0, ref retPages); 218 } 219 } 220 221 return retPages; 222 } 223 224 /// <summary> 225 /// 直接分頁 226 /// </summary> 227 /// <param name="startR">開始行號</param> 228 /// <param name="pages">頁面數組</param> 229 private void Paging_Direct(int startR, ref List<PagingItem> pages) 230 { 231 float p_Height = TableRect.Height; 232 PagingItem p_Item = new PagingItem(); 233 p_Item.PageNum = pages.Count + 1; 234 for (int t = startR; t < RowsList.Count; t++) 235 { 236 // 檢查行內單元格是否不允許分頁兩種情況:條形碼,圖片 237 if (Paging_CheckCell(RowsList[t], p_Height)) 238 { 239 startR = t; 240 pages.Add(p_Item); 241 Paging_Direct(startR, ref pages); 242 break; 243 } 244 else 245 { 246 p_Height -= RowsList[t].RowHeight; 247 if (p_Height <= 0) 248 { 249 startR = t; 250 pages.Add(p_Item); 251 Paging_Direct(startR, ref pages); 252 break; 253 } 254 else 255 { 256 p_Item.IndexList.Add(t); 257 if (t == RowsList.Count - 1) 258 { 259 pages.Add(p_Item); 260 } 261 } 262 } 263 } 264 } 265 266 /// <summary> 267 /// 相對分頁 268 /// </summary> 269 /// <param name="startR">開始序號</param> 270 /// <param name="pages">頁面數組</param> 271 private void Paging_Relative(int startR, ref List<PagingItem> pages) 272 { 273 SplitReportArea(); // 拆分表行 274 float p_Height = TableRect.Height; // 頁面總高 275 PagingItem p_Item = new PagingItem(); // 分頁頁面 276 p_Item.PageNum = pages.Count + 1; // 分頁頁碼 277 bool runNext = false; // 繼續分頁 278 279 #region 每頁打印標題 280 281 // 每頁打印標題 282 if (IsAllPrintTitle) 283 { 284 p_Height -= Get_TableTileHeight(); 285 foreach (Row p_Row in TitleList) 286 p_Item.IndexList.Add(p_Row.RowIndex); 287 } 288 else 289 { 290 if (p_Item.PageNum == 1) // 第一頁特殊處理 291 { 292 p_Height -= Get_TableTileHeight(); 293 foreach (Row p_Row in TitleList) 294 p_Item.IndexList.Add(p_Row.RowIndex); 295 } 296 } 297 298 #endregion 299 300 #region 每頁打印表頭 301 302 // 每頁打印表頭 303 if (IsAllPrintHead) 304 { 305 if (p_Item.PageNum == 1) // 第一頁特殊處理 306 { 307 // 計算表頭前的行高 308 p_Height -= Get_TableHForHeight(); 309 foreach (Row p_Row in HForeList) 310 p_Item.IndexList.Add(p_Row.RowIndex); 311 } 312 313 // 計算表頭行的高度 314 p_Height -= Get_TableHeadHeight(); 315 foreach (Row p_Row in HeadList) 316 p_Item.IndexList.Add(p_Row.RowIndex); 317 } 318 else 319 { 320 if (p_Item.PageNum == 1) // 第一頁特殊處理 321 { 322 // 計算表頭前的行高 323 p_Height -= Get_TableHForHeight(); 324 foreach (Row p_Row in HForeList) 325 p_Item.IndexList.Add(p_Row.RowIndex); 326 327 // 計算表頭行的高度 328 p_Height -= Get_TableHeadHeight(); 329 foreach (Row p_Row in HeadList) 330 p_Item.IndexList.Add(p_Row.RowIndex); 331 } 332 } 333 334 #endregion 335 336 #region 每頁數據區域 337 338 // 每頁數據劃分 339 if (IsAllPrintFoot) 340 { 341 p_Height -= Get_TableFootHeight(); // 表格高度 先減去表尾的高度 342 } 343 for (int t = startR; t < DataList.Count; t++) 344 { 345 // 檢查行內單元格是否不允許分頁兩種情況:條形碼,圖片 346 if (Paging_CheckCell(DataList[t], p_Height)) // 此情況下,單元格不能分割,並且高度超過頁面剩余高度,所以要啟動新的一頁 347 { 348 startR = t; 349 runNext = true; 350 break; 351 } 352 else 353 { 354 p_Height -= DataList[t].RowHeight; 355 if (p_Height <= 0) 356 { 357 startR = t; 358 runNext = true; 359 break; 360 } 361 else 362 { 363 p_Item.IndexList.Add(DataList[t].RowIndex); 364 } 365 } 366 } 367 368 #endregion 369 370 #region 每頁打印表尾 371 372 // 每頁打印表尾 373 if (IsAllPrintFoot) 374 { 375 foreach (Row p_Row in FootList) 376 p_Item.IndexList.Add(p_Row.RowIndex); 377 } 378 379 #endregion 380 381 #region 添加分頁頁面 382 383 pages.Add(p_Item); 384 if (runNext) 385 { 386 Paging_Relative(startR, ref pages); 387 } 388 389 #endregion 390 } 391 392 /// <summary> 393 /// 檢查行內單元格如果是圖片 394 /// 並且合並行數大於1 395 /// </summary> 396 /// <param name="cRow"></param> 397 /// <param name="cHeight"></param> 398 /// <returns></returns> 399 private bool Paging_CheckCell(Row cRow, float cHeight) 400 { 401 foreach (Cell cCell in cRow.RowCells) 402 { 403 if (cCell.IsImage == true) 404 { 405 if (cCell.RectH > cHeight) 406 return true; 407 } 408 } 409 return false; 410 } 411 412 #endregion 413 414 #region 輔助方法 415 416 /// <summary> 417 /// 獲取--報表全部高度 418 /// </summary> 419 /// <returns></returns> 420 private float Get_TableAllHeight() 421 { 422 float retHight = 0; 423 for (int k = 0; k < RowsList.Count; k++) 424 { 425 Row t_Row = RowsList[k]; 426 retHight += t_Row.RowHeight; 427 } 428 return retHight; 429 } 430 431 /// <summary> 432 /// 獲取是否設置了標題、表頭、表尾 中的任意一個 433 /// </summary> 434 /// <returns></returns> 435 private bool Get_IsCusSet_THDF() 436 { 437 string tmType = ""; 438 foreach (Row cusRow in this.RowsList) 439 { 440 tmType = cusRow.RowType.ToLower().Trim(); 441 if (tmType == "t" || tmType == "h" || tmType == "f") 442 return true; 443 } 444 445 return false; 446 } 447 448 /// <summary> 449 /// 獲取--報表標題高度 450 /// </summary> 451 /// <returns></returns> 452 private float Get_TableTileHeight() 453 { 454 float retHight = 0; 455 for (int k = 0; k < TitleList.Count; k++) 456 retHight += TitleList[k].RowHeight; 457 458 return retHight; 459 } 460 461 /// <summary> 462 /// 獲取--報表表頭前高度 463 /// </summary> 464 /// <returns></returns> 465 private float Get_TableHForHeight() 466 { 467 float retHight = 0; 468 for (int k = 0; k < HForeList.Count; k++) 469 retHight += HForeList[k].RowHeight; 470 471 return retHight; 472 } 473 474 /// <summary> 475 /// 獲取--報表表頭高度 476 /// </summary> 477 /// <returns></returns> 478 private float Get_TableHeadHeight() 479 { 480 float retHight = 0; 481 for (int k = 0; k < HeadList.Count; k++) 482 retHight += HeadList[k].RowHeight; 483 return retHight; 484 } 485 486 /// <summary> 487 /// 獲取--報表表尾高度 488 /// </summary> 489 /// <returns></returns> 490 private float Get_TableFootHeight() 491 { 492 float retHight = 0; 493 for (int k = 0; k < FootList.Count; k++) 494 retHight += FootList[k].RowHeight; 495 return retHight; 496 } 497 498 /// <summary> 499 /// 拆分報表區域 500 /// </summary> 501 public void SplitReportArea() 502 { 503 TitleList = new List<Row>(); 504 HForeList = new List<Row>(); 505 HeadList = new List<Row>(); 506 DataList = new List<Row>(); 507 FootList = new List<Row>(); 508 509 for (int m = 0; m < RowsList.Count; m++) 510 { 511 Row mmRow = RowsList[m]; 512 switch (mmRow.RowType.ToLower()) 513 { 514 case "t": // 標題 515 TitleList.Add(mmRow); 516 break; 517 case "h": // 表頭 518 HeadList.Add(mmRow); 519 break; 520 case "f": // 表尾 521 FootList.Add(mmRow); 522 break; 523 case "d": // 數據 524 default: 525 DataList.Add(mmRow); 526 break; 527 } 528 } 529 530 531 // 設置表頭前行集 532 if (TitleList.Count == 0 && HeadList.Count > 0) 533 { 534 List<Row> tmpList = new List<Row>(); 535 for (int n = 0; n < DataList.Count; n++) 536 { 537 if (DataList[n].RowIndex < HeadList[0].RowIndex) 538 { 539 HForeList.Add(DataList[n]); 540 tmpList.Add(DataList[n]); 541 } 542 } 543 544 for (int n = 0; n < tmpList.Count; n++) 545 { 546 DataList.Remove(tmpList[n]); 547 } 548 549 tmpList.Clear(); 550 } 551 552 // 重設表尾 不是每頁打印表尾情況下,那麼表位就去掉 553 if (!IsAllPrintFoot) 554 { 555 foreach (Row tRow in FootList) 556 DataList.Add(tRow); 557 FootList.Clear(); 558 } 559 } 560 561 #endregion 562 } 563 } View Code

4、PagingMakeUp 分頁補充繪制類

1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 5 namespace E_Print 6 { 7 /// <summary> 8 /// 下頁需要補充繪制 9 /// </summary> 10 public class PagingMakeUp 11 { 12 /// <summary> 13 /// 補充單元格 14 /// </summary> 15 private Cell _makeupCell; 16 17 /// <summary> 18 /// 補充高度 19 /// </summary> 20 private float _makeupHeight; 21 22 /// <summary> 23 /// 構造函數 24 /// </summary> 25 public PagingMakeUp() 26 { 27 _makeupCell = new Cell(); 28 _makeupHeight = 0; 29 } 30 31 /// <summary> 32 /// 獲取--設置--補充單元格 33 /// </summary> 34 public Cell MakeupCell 35 { 36 get { return _makeupCell; } 37 set { _makeupCell = value; } 38 } 39 40 /// <summary> 41 /// 獲取--設置--補充高度 42 /// </summary> 43 public float MakeupHeight 44 { 45 get { return _makeupHeight; } 46 set { _makeupHeight = value; } 47 } 48 49 } 50 } View Code

5、IObjectSafety 抽象接口類

1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 using System.Runtime.InteropServices; 5 6 namespace E_Print 7 { 8 /// <summary> 9 /// 接口抽象基類 10 /// </summary> 11 [ComImport, GuidAttribute("CB5BDC81-93C1-11CF-8F20-00805F2CD064")] 12 [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 13 public interface IObjectSafety 14 { 15 [PreserveSig] 16 int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions); 17 18 [PreserveSig()] 19 int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions); 20 } 21 } View Code

6、預覽效果

7、我們可以通過源碼中的 EPrintTest.exe 打印Winform 實例 ,來執行示范,

     通過WEB前端js 生成打印的TABLE的 RptData.xml格式 數據,在WINForm中直接使用

     如果在網頁中,通過JS 直接傳給打印控件就OK



 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved