网页WEB打印控件制作

在WEB系统中,打印的确是比较烦人的问题,如果我们能制作一个属于自己的自定义的打印插件,那么我们在后续自定义打印的时候能随心所欲的控制打印,这样的效果对于程序员来说是非常开心的一件事件,本文将自己开发编写的C# 制作的HTML打印插件分享出来,让有同样需求的朋友提供一个参考;此插件是基于Microsoft .NET Framework 2.0 开发的,缺点是每台客户端在安装插件时,必须要安装Microsoft .NET Framework 2.0 ;本插件能实现 页眉、页脚、表头、标题、表尾的分页打印;支持纸张类型、自动补充空行等功能;由于技术有限,肯定有很多不足的地方,请批评指正!

由于本打印插件是基于我们开发平台的报表基础来开发设计的,所以打印控件的原理:通过JS将页面表格数据生成固定格式的XML字符串(图片通过64base图片格式)传送给打印插件,有打印插件自主绘图生成打印页面。E_Print插件可以在WEB或WinForm中使用:

打印插件完整源码:E_Print.rar   (包含插件源码、打包程序、winform调试DEMO)

下面贴出源码:(在源码中有详细的注释说明)

1、PrintControl 打印插件类

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

2、ReportDraw 打印绘制类

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

3、PagingCalc 分页计算类

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

4、PagingMakeUp 分页补充绘制类

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

5、IObjectSafety 抽象接口类

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

6、预览效果

7、我们可以通过源码中的 EPrintTest.exe 打印Winform 实例 ,来执行示范,

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

如果在网页中,通过JS 直接传给打印控件就OK

时间: 2024-10-04 07:24:26

网页WEB打印控件制作的相关文章

网页WEB打印控件制作 开放源码可以调试

在WEB系统中,打印的确是比较烦人的问题,如果我们能制作一个属于自己的自定义的打印插件,那么我们在后续自定义打印的时候能随心所欲的控制打印,这样的效果对于程序员来说是非常开心的一件事件,本文将自己开发编写的C# 制作的HTML打印插件分享出来,让有同样需求的朋友提供一个参考:此插件是基于Microsoft .NET Framework 2.0 开发的,缺点是每台客户端在安装插件时,必须要安装Microsoft .NET Framework 2.0 :本插件能实现 页眉.页脚.表头.标题.表尾的分

网页WEB打印控件制作-开放源码

在WEB系统中,打印的确是比较烦人的问题,如果我们能制作一个属于自己的自定义的打印插件,那么我们在后续自定义打印的时候能随心所欲的控制打印,这样的效果对于程序员来说是非常开心的一件事件,本文将自己开发编写的C# 制作的HTML打印插件分享出来,让有同样需求的朋友提供一个参考:此插件是基于Microsoft .NET Framework 2.0 开发的,缺点是每台客户端在安装插件时,必须要安装Microsoft .NET Framework 2.0 :本插件能实现 页眉.页脚.表头.标题.表尾的分

分享免费的web打印控件puzu

在WEB系统中,打印的确是个烦人的问题----特别是你的应用环境又有很多种类的打印机.如果自己开发打印控件,可能因为项目时间紧而来不及.前段时间有机会接触了一下WEB打印.在博客园.CSDN以及各个论坛上找了老半天,终于顺利的完成了公司项目.现在就结合我的应用体验,将市面上的所有的免费打印控件为大家做一个介绍. 1. DLPrinter 这个打印控件完全免费,界面还不错,使用也较为简单,支持打印预览.直接打印.可设置页眉.页脚.页边距.打印份数.纸张大小等信息,悲剧的是这大哥在07年做了第二次更

Web打印控件

Lodop是什么? 有人说她是Web打印控件,因为她能打印.在浏览器中以插件的形式出现,用简单一行语句就把整个网页打印出来: 有人说她是打印编程接口,因为她介于浏览器和打印设备之间,是个通道和桥梁,几乎能想到的打印控制事项都能做到: 有人说她是JavaScript的扩展,因为她所有功能就那么几个语句,和JS语法一样,一看就明白个究竟: 有人说她是报表打印工具,因为那个add_print_table语句把报表统计的那点事弄了个明明白白: 有人说她是条码打印工具,因为用了她再也不用后台生成条码图片了

在.net Core 使用PDF模板文件生成PDF文件,代替WEB打印控件!

这几天找WEB打印控件,要么收费的,要么免费的只能在IE里用! 我只想简单的打个标签纸!百度2天,看到一老兄说可以用PDF,然后又开始百度..找到了一篇文章 http://www.jianshu.com/p/d518d0988621    本文代码全部摘抄至这篇文章,发文只为记录! 不同的是我导入的库是iTextSharp.LGPLv2.Core.Fix 开始 一.先用word制作好模板文件,标签打印的话注意页边距,然后另存为PDF格式文件 二.然后下载adobe acrobat pro,创建时

对于四方web打印控件的看法

web打印控件比较多,但是基本都收费.但是四方的虽然不收费,就是得动动手了. 要谈到控件的实用性,便捷性,当然四方的会更胜一筹.在它的demo例子中,像设置默认打印机,纸张自定义大小,页眉页脚,页边距,连续打印等功能都可以轻松的实现. 对于那些需要web打印功能,但囊中羞涩,或者小范围使用,盈利未知的创业项目是比较实用的.如果要正真能够顺畅的使用,随心所欲,付费也是投资成本不可避免的了. 四方web打印控件,使用于IE作为客户端的所有应用,与服务器端开发语言无关,即PAZU支持所有的开发语言开发

web表格控件制作圆环图

工具/原料 web表格控件:FineReport7.1.1 大小:148.2M 适用平台:windows/linux 1. 描述 圆环图类似于饼图,显示个体与整体之间的关系,可以直观了解个体部分所占整体部分的百分比,但是不同于饼图的是,圆环图可以包含多个分类,即多层圆环图,可以从圆环的径向上去比较不同分类下同一系列的数据的变化趋势. 2. 示例 下面我们制作一张圆环图图表,显示各个地区产品的销量情况,在查看每个地区产品销量所在份额的同时,对比同一个产品在不同地区的销量差异情况. 2.1 数据准备

WEB打印控件Lodop应用实例

asp.net环境下LODOP打印控件的应用例子. 这篇文章发布在我的个人网站上,下面是原文的链接地址. http://www.itstu.net/plus/view.php?aid=95

Web打印控件Lodop

将如下代码添加到页面: <object id="LODOP_OB" classid="clsid:2105C259-1E0C-4534-8141-A753534CB4CA" width="0" height="0"> <embed id="LODOP_EM" type="application/x-print-lodop" width="0" hei