網頁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)數組

   下面貼出源碼:(在源碼中有詳細的註釋說明)ide

一、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

 

二、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

三、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

四、PagingMakeUp 分頁補充繪製類ui

 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

五、IObjectSafety 抽象接口類this

 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

六、預覽效果編碼

七、咱們能夠經過源碼中的 EPrintTest.exe 打印Winform 實例 ,來執行示範,

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

     若是在網頁中,經過JS 直接傳給打印控件就OK

相關文章
相關標籤/搜索