heting

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  40 随笔 :: 9 文章 :: 45 评论 :: 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 贺挺 阅读(660) 评论(0)  编辑  收藏 所属分类: c#范例

只有注册用户登录后才能发表评论。


网站导航: