heting

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            40 隨筆 :: 9 文章 :: 45 評(píng)論 :: 0 Trackbacks
            1using System;
            2
            3using System.Text;
            4
            5using System.Collections;
            6
            7using System.Collections.Generic;
            8
            9using System.Drawing;
           10
           11using System.Drawing.Printing;
           12
           13using System.Data;
           14
           15using System.Windows.Forms;
           16
           17namespace EtaocnCS
           18{
           19    public class DataGridViewPrinter
           20    {
           21        private DataGridView TheDataGridView; // The DataGridView Control which will be printed
           22
           23        private PrintDocument ThePrintDocument; // The PrintDocument to be used for printing
           24
           25        private bool IsCenterOnPage; // Determine if the report will be printed in the Top-Center of the page
           26
           27        private bool IsWithTitle; // Determine if the page contain title text
           28
           29        private string TheTitleText; // The title text to be printed in each page (if IsWithTitle is set to true)
           30
           31        private Font TheTitleFont; // The font to be used with the title text (if IsWithTitle is set to true)
           32
           33        private Color TheTitleColor; // The color to be used with the title text (if IsWithTitle is set to true)
           34
           35        private bool IsWithPaging; // Determine if paging is used
           36
           37        static int CurrentRow; // A static parameter that keep track on which Row (in the DataGridView control) that should be printed
           38
           39        static int PageNumber;
           40
           41        private int PageWidth;
           42
           43        private int PageHeight;
           44
           45        private int LeftMargin;
           46
           47        private int TopMargin;
           48
           49        private int RightMargin;
           50
           51        private int BottomMargin;
           52
           53        private float CurrentY; // A parameter that keep track on the y coordinate of the page, so the next object to be printed will start from this y coordinate
           54
           55        private float RowHeaderHeight;
           56
           57        private List<float> RowsHeight;
           58
           59        private List<float> ColumnsWidth;
           60
           61        private float TheDataGridViewWidth;
           62
           63
           64
           65        // Maintain a generic list to hold start/stop points for the column printing
           66
           67        // This will be used for wrapping in situations where the DataGridView will not fit on a single page
           68
           69        private List<int[]> mColumnPoints;
           70
           71        private List<float> mColumnPointsWidth;
           72
           73        private int mColumnPoint;
           74
           75
           76
           77        // The class constructor
           78
           79        public DataGridViewPrinter(DataGridView aDataGridView, PrintDocument aPrintDocument, bool CenterOnPage, bool WithTitle, string aTitleText, Font aTitleFont, Color aTitleColor, bool WithPaging)
           80        {
           81
           82            TheDataGridView = aDataGridView;
           83
           84            ThePrintDocument = aPrintDocument;
           85
           86            IsCenterOnPage = CenterOnPage;
           87
           88            IsWithTitle = WithTitle;
           89
           90            TheTitleText = aTitleText;
           91
           92            TheTitleFont = aTitleFont;
           93
           94            TheTitleColor = aTitleColor;
           95
           96            IsWithPaging = WithPaging;
           97
           98            PageNumber = 0;
           99
          100            RowsHeight = new List<float>();
          101
          102            ColumnsWidth = new List<float>();
          103
          104            mColumnPoints = new List<int[]>();
          105
          106            mColumnPointsWidth = new List<float>();
          107
          108            // Claculating the PageWidth and the PageHeight
          109
          110            if (!ThePrintDocument.DefaultPageSettings.Landscape)
          111            {
          112
          113                PageWidth = ThePrintDocument.DefaultPageSettings.PaperSize.Width;
          114
          115                PageHeight = ThePrintDocument.DefaultPageSettings.PaperSize.Height;
          116
          117            }

          118
          119            else
          120            {
          121
          122                PageHeight = ThePrintDocument.DefaultPageSettings.PaperSize.Width;
          123
          124                PageWidth = ThePrintDocument.DefaultPageSettings.PaperSize.Height;
          125
          126            }

          127
          128            // Claculating the page margins
          129
          130            LeftMargin = ThePrintDocument.DefaultPageSettings.Margins.Left;
          131
          132            TopMargin = ThePrintDocument.DefaultPageSettings.Margins.Top;
          133
          134            RightMargin = ThePrintDocument.DefaultPageSettings.Margins.Right;
          135
          136            BottomMargin = ThePrintDocument.DefaultPageSettings.Margins.Bottom;
          137
          138            // First, the current row to be printed is the first row in the DataGridView control
          139
          140            CurrentRow = 0;
          141
          142        }

          143
          144        // The function that calculate the height of each row (including the header row), the width of each column (according to the longest text in all its cells including the header cell), and the whole DataGridView width
          145
          146        private void Calculate(Graphics g)
          147        {
          148
          149            if (PageNumber == 0// Just calculate once
          150            {
          151
          152                SizeF tmpSize = new SizeF();
          153
          154                Font tmpFont;
          155
          156                float tmpWidth;
          157
          158                TheDataGridViewWidth = 0;
          159
          160                for (int i = 0; i < TheDataGridView.Columns.Count; i++)
          161                {
          162
          163                    tmpFont = TheDataGridView.ColumnHeadersDefaultCellStyle.Font;
          164
          165                    if (tmpFont == null// If there is no special HeaderFont style, then use the default DataGridView font style
          166
          167                        tmpFont = TheDataGridView.DefaultCellStyle.Font;
          168
          169                    tmpSize = g.MeasureString(TheDataGridView.Columns[i].HeaderText, tmpFont);
          170
          171                    tmpWidth = tmpSize.Width;
          172
          173                    RowHeaderHeight = tmpSize.Height;
          174
          175                    for (int j = 0; j < TheDataGridView.Rows.Count; j++)
          176                    {
          177
          178                        tmpFont = TheDataGridView.Rows[j].DefaultCellStyle.Font;
          179
          180                        if (tmpFont == null// If the there is no special font style of the CurrentRow, then use the default one associated with the DataGridView control
          181
          182                            tmpFont = TheDataGridView.DefaultCellStyle.Font;
          183
          184                        tmpSize = g.MeasureString("Anything", tmpFont);
          185
          186                        RowsHeight.Add(tmpSize.Height);
          187
          188                        tmpSize = g.MeasureString(TheDataGridView.Rows[j].Cells[i].EditedFormattedValue.ToString(), tmpFont);
          189
          190                        if (tmpSize.Width > tmpWidth)
          191
          192                            tmpWidth = tmpSize.Width;
          193
          194                    }

          195
          196                    if (TheDataGridView.Columns[i].Visible)
          197
          198                        TheDataGridViewWidth += tmpWidth;
          199
          200                    ColumnsWidth.Add(tmpWidth);
          201
          202                }

          203
          204                // Define the start/stop column points based on the page width and the DataGridView Width
          205
          206                // We will use this to determine the columns which are drawn on each page and how wrapping will be handled
          207
          208                // By default, the wrapping will occurr such that the maximum number of columns for a page will be determine
          209
          210                int k;
          211
          212                int mStartPoint = 0;
          213
          214                for (k = 0; k < TheDataGridView.Columns.Count; k++)
          215
          216                    if (TheDataGridView.Columns[k].Visible)
          217                    {
          218
          219                        mStartPoint = k;
          220
          221                        break;
          222
          223                    }

          224
          225                int mEndPoint = TheDataGridView.Columns.Count;
          226
          227                for (k = TheDataGridView.Columns.Count - 1; k >= 0; k--)
          228
          229                    if (TheDataGridView.Columns[k].Visible)
          230                    {
          231
          232                        mEndPoint = k + 1;
          233
          234                        break;
          235
          236                    }

          237
          238                float mTempWidth = TheDataGridViewWidth;
          239
          240                float mTempPrintArea = (float)PageWidth - (float)LeftMargin - (float)RightMargin;
          241
          242
          243
          244                // We only care about handling where the total datagridview width is bigger then the print area
          245
          246                if (TheDataGridViewWidth > mTempPrintArea)
          247                {
          248
          249                    mTempWidth = 0.0F;
          250
          251                    for (k = 0; k < TheDataGridView.Columns.Count; k++)
          252                    {
          253
          254                        if (TheDataGridView.Columns[k].Visible)
          255                        {
          256
          257                            mTempWidth += ColumnsWidth[k];
          258
          259                            // If the width is bigger than the page area, then define a new column print range
          260
          261                            if (mTempWidth > mTempPrintArea)
          262                            {
          263
          264                                mTempWidth -= ColumnsWidth[k];
          265
          266                                mColumnPoints.Add(new int[] { mStartPoint, mEndPoint });
          267
          268                                mColumnPointsWidth.Add(mTempWidth);
          269
          270                                mStartPoint = k;
          271
          272                                mTempWidth = ColumnsWidth[k];
          273
          274                            }

          275
          276                        }

          277
          278                        // Our end point is actually one index above the current index
          279
          280                        mEndPoint = k + 1;
          281
          282                    }

          283
          284                }

          285
          286                // Add the last set of columns
          287
          288                mColumnPoints.Add(new int[] { mStartPoint, mEndPoint });
          289
          290                mColumnPointsWidth.Add(mTempWidth);
          291
          292                mColumnPoint = 0;
          293
          294            }

          295
          296        }

          297
          298        // The funtion that print the title, page number, and the header row
          299
          300        private void DrawHeader(Graphics g)
          301        {
          302
          303            CurrentY = (float)TopMargin;
          304
          305            // Printing the page number (if isWithPaging is set to true)
          306
          307            if (IsWithPaging)
          308            {
          309
          310                PageNumber = PageNumber+1;
          311
          312                string PageString = "Page " + PageNumber.ToString();
          313
          314                StringFormat PageStringFormat = new StringFormat();
          315
          316                PageStringFormat.Trimming = StringTrimming.Word;
          317
          318                PageStringFormat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit | StringFormatFlags.NoClip;
          319
          320                PageStringFormat.Alignment = StringAlignment.Far;
          321
          322                Font PageStringFont = new Font("Tahoma"8, FontStyle.Regular, GraphicsUnit.Point);
          323
          324                RectangleF PageStringRectangle = new RectangleF((float)LeftMargin, CurrentY, (float)PageWidth - (float)RightMargin - (float)LeftMargin, g.MeasureString(PageString, PageStringFont).Height);
          325
          326                g.DrawString(PageString, PageStringFont, new SolidBrush(Color.Black), PageStringRectangle, PageStringFormat);
          327
          328                CurrentY += g.MeasureString(PageString, PageStringFont).Height;
          329
          330            }

          331
          332            // Printing the title (if IsWithTitle is set to true)
          333
          334            if (IsWithTitle)
          335            {
          336
          337                StringFormat TitleFormat = new StringFormat();
          338
          339                TitleFormat.Trimming = StringTrimming.Word;
          340
          341                TitleFormat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit | StringFormatFlags.NoClip;
          342
          343                if (IsCenterOnPage)
          344
          345                    TitleFormat.Alignment = StringAlignment.Center;
          346
          347                else
          348
          349                    TitleFormat.Alignment = StringAlignment.Near;
          350
          351                RectangleF TitleRectangle = new RectangleF((float)LeftMargin, CurrentY, (float)PageWidth - (float)RightMargin - (float)LeftMargin, g.MeasureString(TheTitleText, TheTitleFont).Height);
          352
          353                g.DrawString(TheTitleText, TheTitleFont, new SolidBrush(TheTitleColor), TitleRectangle, TitleFormat);
          354
          355                CurrentY += g.MeasureString(TheTitleText, TheTitleFont).Height;
          356
          357            }

          358
          359            // Calculating the starting x coordinate that the printing process will start from
          360
          361            float CurrentX = (float)LeftMargin;
          362
          363            if (IsCenterOnPage)
          364
          365                CurrentX += (((float)PageWidth - (float)RightMargin - (float)LeftMargin) - mColumnPointsWidth[mColumnPoint]) / 2.0F;
          366
          367            // Setting the HeaderFore style
          368
          369            Color HeaderForeColor = TheDataGridView.ColumnHeadersDefaultCellStyle.ForeColor;
          370
          371            if (HeaderForeColor.IsEmpty) // If there is no special HeaderFore style, then use the default DataGridView style
          372
          373                HeaderForeColor = TheDataGridView.DefaultCellStyle.ForeColor;
          374
          375            SolidBrush HeaderForeBrush = new SolidBrush(HeaderForeColor);
          376
          377            // Setting the HeaderBack style
          378
          379            Color HeaderBackColor = TheDataGridView.ColumnHeadersDefaultCellStyle.BackColor;
          380
          381            if (HeaderBackColor.IsEmpty) // If there is no special HeaderBack style, then use the default DataGridView style
          382
          383                HeaderBackColor = TheDataGridView.DefaultCellStyle.BackColor;
          384
          385            SolidBrush HeaderBackBrush = new SolidBrush(HeaderBackColor);
          386
          387            // Setting the LinePen that will be used to draw lines and rectangles (derived from the GridColor property of the DataGridView control)
          388
          389            Pen TheLinePen = new Pen(TheDataGridView.GridColor, 1);
          390
          391            // Setting the HeaderFont style
          392
          393            Font HeaderFont = TheDataGridView.ColumnHeadersDefaultCellStyle.Font;
          394
          395            if (HeaderFont == null// If there is no special HeaderFont style, then use the default DataGridView font style
          396
          397                HeaderFont = TheDataGridView.DefaultCellStyle.Font;
          398
          399            // Calculating and drawing the HeaderBounds        
          400
          401            RectangleF HeaderBounds = new RectangleF(CurrentX, CurrentY, mColumnPointsWidth[mColumnPoint], RowHeaderHeight);
          402
          403            g.FillRectangle(HeaderBackBrush, HeaderBounds);
          404
          405            // Setting the format that will be used to print each cell of the header row
          406
          407            StringFormat CellFormat = new StringFormat();
          408
          409            CellFormat.Trimming = StringTrimming.Word;
          410
          411            CellFormat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit | StringFormatFlags.NoClip;
          412
          413            // Printing each visible cell of the header row
          414
          415            RectangleF CellBounds;
          416
          417            float ColumnWidth;
          418
          419            for (int i = (int)mColumnPoints[mColumnPoint].GetValue(0); i < (int)mColumnPoints[mColumnPoint].GetValue(1); i++)
          420            {
          421
          422                if (!TheDataGridView.Columns[i].Visible) continue// If the column is not visible then ignore this iteration
          423
          424                ColumnWidth = ColumnsWidth[i];
          425
          426                // Check the CurrentCell alignment and apply it to the CellFormat
          427
          428                if (TheDataGridView.ColumnHeadersDefaultCellStyle.Alignment.ToString().Contains("Right"))
          429
          430                    CellFormat.Alignment = StringAlignment.Far;
          431
          432                else if (TheDataGridView.ColumnHeadersDefaultCellStyle.Alignment.ToString().Contains("Center"))
          433
          434                    CellFormat.Alignment = StringAlignment.Center;
          435
          436                else
          437
          438                    CellFormat.Alignment = StringAlignment.Near;
          439
          440                CellBounds = new RectangleF(CurrentX, CurrentY, ColumnWidth, RowHeaderHeight);
          441
          442                // Printing the cell text
          443
          444                g.DrawString(TheDataGridView.Columns[i].HeaderText, HeaderFont, HeaderForeBrush, CellBounds, CellFormat);
          445
          446                // Drawing the cell bounds
          447
          448                if (TheDataGridView.RowHeadersBorderStyle != DataGridViewHeaderBorderStyle.None) // Draw the cell border only if the HeaderBorderStyle is not None
          449
          450                    g.DrawRectangle(TheLinePen, CurrentX, CurrentY, ColumnWidth, RowHeaderHeight);
          451
          452                CurrentX += ColumnWidth;
          453
          454            }

          455
          456            CurrentY += RowHeaderHeight;
          457
          458        }

          459
          460        // The function that print a bunch of rows that fit in one page
          461
          462        // When it returns true, meaning that there are more rows still not printed, so another PagePrint action is required
          463
          464        // When it returns false, meaning that all rows are printed (the CureentRow parameter reaches the last row of the DataGridView control) and no further PagePrint action is required
          465
          466        private bool DrawRows(Graphics g)
          467        {
          468
          469            // Setting the LinePen that will be used to draw lines and rectangles (derived from the GridColor property of the DataGridView control)
          470
          471            Pen TheLinePen = new Pen(TheDataGridView.GridColor, 1);
          472
          473            // The style paramters that will be used to print each cell
          474
          475            Font RowFont;
          476
          477            Color RowForeColor;
          478
          479            Color RowBackColor;
          480
          481            SolidBrush RowForeBrush;
          482
          483            SolidBrush RowBackBrush;
          484
          485            SolidBrush RowAlternatingBackBrush;
          486
          487            // Setting the format that will be used to print each cell
          488
          489            StringFormat CellFormat = new StringFormat();
          490
          491            CellFormat.Trimming = StringTrimming.Word;
          492
          493            CellFormat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit;
          494
          495            // Printing each visible cell
          496
          497            RectangleF RowBounds;
          498
          499            float CurrentX;
          500
          501            float ColumnWidth;
          502
          503            while (CurrentRow < TheDataGridView.Rows.Count)
          504            {
          505
          506                if (TheDataGridView.Rows[CurrentRow].Visible) // Print the cells of the CurrentRow only if that row is visible
          507                {
          508
          509                    // Setting the row font style
          510
          511                    RowFont = TheDataGridView.Rows[CurrentRow].DefaultCellStyle.Font;
          512
          513                    if (RowFont == null// If the there is no special font style of the CurrentRow, then use the default one associated with the DataGridView control
          514
          515                        RowFont = TheDataGridView.DefaultCellStyle.Font;
          516
          517                    // Setting the RowFore style
          518
          519                    RowForeColor = TheDataGridView.Rows[CurrentRow].DefaultCellStyle.ForeColor;
          520
          521                    if (RowForeColor.IsEmpty) // If the there is no special RowFore style of the CurrentRow, then use the default one associated with the DataGridView control
          522
          523                        RowForeColor = TheDataGridView.DefaultCellStyle.ForeColor;
          524
          525                    RowForeBrush = new SolidBrush(RowForeColor);
          526
          527                    // Setting the RowBack (for even rows) and the RowAlternatingBack (for odd rows) styles
          528
          529                    RowBackColor = TheDataGridView.Rows[CurrentRow].DefaultCellStyle.BackColor;
          530
          531                    if (RowBackColor.IsEmpty) // If the there is no special RowBack style of the CurrentRow, then use the default one associated with the DataGridView control
          532                    {
          533
          534                        RowBackBrush = new SolidBrush(TheDataGridView.DefaultCellStyle.BackColor);
          535
          536                        RowAlternatingBackBrush = new SolidBrush(TheDataGridView.AlternatingRowsDefaultCellStyle.BackColor);
          537
          538                    }

          539
          540                    else // If the there is a special RowBack style of the CurrentRow, then use it for both the RowBack and the RowAlternatingBack styles
          541                    {
          542
          543                        RowBackBrush = new SolidBrush(RowBackColor);
          544
          545                        RowAlternatingBackBrush = new SolidBrush(RowBackColor);
          546
          547                    }

          548
          549                    // Calculating the starting x coordinate that the printing process will start from
          550
          551                    CurrentX = (float)LeftMargin;
          552
          553                    if (IsCenterOnPage)
          554
          555                        CurrentX += (((float)PageWidth - (float)RightMargin - (float)LeftMargin) - mColumnPointsWidth[mColumnPoint]) / 2.0F;
          556
          557                    // Calculating the entire CurrentRow bounds                
          558
          559                    RowBounds = new RectangleF(CurrentX, CurrentY, mColumnPointsWidth[mColumnPoint], RowsHeight[CurrentRow]);
          560
          561                    // Filling the back of the CurrentRow
          562
          563                    if (CurrentRow % 2 == 0)
          564
          565                        g.FillRectangle(RowBackBrush, RowBounds);
          566
          567                    else
          568
          569                        g.FillRectangle(RowAlternatingBackBrush, RowBounds);
          570
          571                    // Printing each visible cell of the CurrentRow                
          572
          573                    for (int CurrentCell = (int)mColumnPoints[mColumnPoint].GetValue(0); CurrentCell < (int)mColumnPoints[mColumnPoint].GetValue(1); CurrentCell++)
          574                    {
          575
          576                        if (!TheDataGridView.Columns[CurrentCell].Visible) continue// If the cell is belong to invisible column, then ignore this iteration
          577
          578                        // Check the CurrentCell alignment and apply it to the CellFormat
          579
          580                        if (TheDataGridView.Columns[CurrentCell].DefaultCellStyle.Alignment.ToString().Contains("Right"))
          581
          582                            CellFormat.Alignment = StringAlignment.Far;
          583
          584                        else if (TheDataGridView.Columns[CurrentCell].DefaultCellStyle.Alignment.ToString().Contains("Center"))
          585
          586                            CellFormat.Alignment = StringAlignment.Center;
          587
          588                        else
          589
          590                            CellFormat.Alignment = StringAlignment.Near;
          591
          592
          593
          594                        ColumnWidth = ColumnsWidth[CurrentCell];
          595
          596                        RectangleF CellBounds = new RectangleF(CurrentX, CurrentY, ColumnWidth, RowsHeight[CurrentRow]);
          597
          598                        // Printing the cell text
          599
          600                        g.DrawString(TheDataGridView.Rows[CurrentRow].Cells[CurrentCell].EditedFormattedValue.ToString(), RowFont, RowForeBrush, CellBounds, CellFormat);
          601
          602
          603
          604                        // Drawing the cell bounds
          605
          606                        if (TheDataGridView.CellBorderStyle != DataGridViewCellBorderStyle.None) // Draw the cell border only if the CellBorderStyle is not None
          607
          608                            g.DrawRectangle(TheLinePen, CurrentX, CurrentY, ColumnWidth, RowsHeight[CurrentRow]);
          609
          610                        CurrentX += ColumnWidth;
          611
          612                    }

          613
          614                    CurrentY += RowsHeight[CurrentRow];
          615
          616                    // Checking if the CurrentY is exceeds the page boundries
          617
          618                    // If so then exit the function and returning true meaning another PagePrint action is required
          619
          620                    if ((int)CurrentY > (PageHeight - TopMargin - BottomMargin))
          621                    {
          622
          623                        CurrentRow++;
          624
          625                        return true;
          626
          627                    }

          628
          629                }

          630
          631                CurrentRow++;
          632
          633            }

          634
          635            CurrentRow = 0;
          636
          637            mColumnPoint++// Continue to print the next group of columns
          638
          639            if (mColumnPoint == mColumnPoints.Count) // Which means all columns are printed
          640            {
          641
          642                mColumnPoint = 0;
          643
          644                return false;
          645
          646            }

          647
          648            else
          649
          650                return true;
          651
          652        }

          653
          654        // The method that calls all other functions
          655
          656        public bool DrawDataGridView(Graphics g)
          657        {
          658
          659            try
          660            {
          661
          662                Calculate(g);
          663               
          664
          665                DrawHeader(g);
          666                IsWithTitle = false;
          667                bool bContinue = DrawRows(g);
          668
          669                return bContinue;
          670
          671            }

          672
          673            catch (Exception ex)
          674            {
          675
          676                MessageBox.Show("Operation failed: " + ex.Message.ToString(), Application.ProductName + " - Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
          677
          678                return false;
          679
          680            }

          681
          682        }

          683
          684
          685    }

          686}

          687
          688
          689
          690
          691
          posted on 2009-08-06 17:31 賀挺 閱讀(674) 評(píng)論(0)  編輯  收藏 所屬分類: c#范例
          主站蜘蛛池模板: 龙江县| 东乌珠穆沁旗| 信宜市| 广河县| 宁夏| 壶关县| 翁牛特旗| 石阡县| 松滋市| 久治县| 江北区| 织金县| 太康县| 盘山县| 苏尼特右旗| 丹棱县| 民勤县| 荔波县| 阿拉善左旗| 金山区| 稷山县| 峨眉山市| 桂平市| 高安市| 临猗县| 保靖县| 阿合奇县| 安义县| 治县。| 德昌县| 连州市| 玉龙| 伊吾县| 疏勒县| 永平县| 咸宁市| 鞍山市| 乐东| 张家口市| 宣化县| 广宗县|