打印Datagridview中表格数据---c#.net
2009-11-06 21:13
471 查看
这是我在项目中使用的,肯定能用的。以前发的那个版本是初期的,现在来发版本2。请大家多多指教哦。不过很久没看过这个文件的代码了,有些注释连我自己都看不懂了。大家凑合着看吧。
using System; using System.Text; using System.Collections; using System.Collections.Generic; using System.Drawing; using System.Drawing.Printing; using System.Data; using System.Windows.Forms; using System.IO; using System.Data.SqlClient; using System.ComponentModel; class DataGridViewPrinter { private DataGridView TheDataGridView; // The DataGridView Control which will be printed private PrintDocument ThePrintDocument; // The PrintDocument to be used for printing private bool IsCenterOnPage; // Determine if the report will be printed in the Top-Center of the page private bool IsWithTitle; // Determine if the page contain title text private string TheTitleText; // The title text to be printed in each page (if IsWithTitle is set to true) private string TheTitleTextTwo;//the second title text private Font TheTitleFont; // The font to be used with the title text (if IsWithTitle is set to true) private Font TheTitleFontTwo;//The second font to be used with the second text private Color TheTitleColor; // The color to be used with the title text (if IsWithTitle is set to true) private bool IsWithPaging; // Determine if paging is used static int CurrentRow; // A static parameter that keep track on which Row (in the DataGridView control) that should be printed static int PageNumber; static int PageNumberson; static int lastnumber;// take the value of last mColumnPoints private int PageWidth; private int PageHeight; private int LeftMargin; private int TopMargin; private int RightMargin; private int BottomMargin; 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 private float RowHeaderHeight; private List<float> RowsHeight; private List<float> ColumnsWidth; private float TheDataGridViewWidth; // Maintain a generic list to hold start/stop points for the column printing // This will be used for wrapping in situations where the DataGridView will not fit on a single page private List<int[]> mColumnPoints; private List<float> mColumnPointsWidth; private int mColumnPoint; //when flag=0, btnPrint_Click;when flag=1 and then flag=2,btnPrintPreview_Click;when flag=3 or above 3,btnPrintPreview.print(); public static int flag;//sign 这个我自己也忘了。 public static bool hasmorepages;// 用来记录是否是多个分页 // The class constructor public DataGridViewPrinter(DataGridView aDataGridView, PrintDocument aPrintDocument, bool CenterOnPage, bool WithTitle, string aTitleText, string bTitleText, Font aTitleFont, Font bTitleFont, Color aTitleColor, bool WithPaging) { TheDataGridView = aDataGridView; ThePrintDocument = aPrintDocument; IsCenterOnPage = CenterOnPage; IsWithTitle = WithTitle; TheTitleText = aTitleText; TheTitleTextTwo = bTitleText; TheTitleFont = aTitleFont; TheTitleFontTwo = bTitleFont; TheTitleColor = aTitleColor; IsWithPaging = WithPaging; PageNumber = 0; PageNumberson = 0; RowsHeight = new List<float>(); ColumnsWidth = new List<float>(); mColumnPoints = new List<int[]>(); mColumnPointsWidth = new List<float>(); // Calculating the PageWidth and the PageHeight if (!ThePrintDocument.DefaultPageSettings.Landscape) { PageWidth = ThePrintDocument.DefaultPageSettings.PaperSize.Width; PageHeight = ThePrintDocument.DefaultPageSettings.PaperSize.Height; } else { PageHeight = ThePrintDocument.DefaultPageSettings.PaperSize.Width; PageWidth = ThePrintDocument.DefaultPageSettings.PaperSize.Height; } // Calculating the page margins LeftMargin = ThePrintDocument.DefaultPageSettings.Margins.Left; TopMargin = ThePrintDocument.DefaultPageSettings.Margins.Top; RightMargin = ThePrintDocument.DefaultPageSettings.Margins.Right; BottomMargin = ThePrintDocument.DefaultPageSettings.Margins.Bottom; // First, the current row to be printed is the first row in the DataGridView control CurrentRow = 0; flag = 0; hasmorepages = false; lastnumber = 0; } /// <summary> /// 将浮点数进位成整数 /// </summary> /// <param name="num"></param> /// <returns></returns> private float intergered(float num) { float num_interger; int point = 0;//小数点的位置 string num_temp = num.ToString(); for (int i = 0; i < num_temp.Length; i++) { if (num_temp[i] == '.') { point = i; break; } } if (point == 0) num_interger = num; else num_interger = Convert.ToSingle(num_temp.Substring(0, point + 1)) + 1; return num_interger; } // 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 private void Calculate(Graphics g) { //green添加begin float totalwidth = (float)PageWidth - (float)LeftMargin - (float)RightMargin;//总宽度 int cols = 0;//记录列数 float minwidth;//最小宽度 //float minheight=30;//最小高度 for (int ic = 0; ic < TheDataGridView.Columns.Count; ic++)//calculate the numbers of columns { if (TheDataGridView.Columns[ic].Visible) cols++; } minwidth = totalwidth / cols; //end if (PageNumber == 0) // Just calculate once { SizeF tmpSize = new SizeF(); Font tmpFont; float tmpWidth = minwidth; TheDataGridViewWidth = 0; for (int i = 0; i < TheDataGridView.Columns.Count; i++) { tmpFont = TheDataGridView.ColumnHeadersDefaultCellStyle.Font; if (tmpFont == null) // If there is no special HeaderFont style, then use the default DataGridView font style tmpFont = TheDataGridView.DefaultCellStyle.Font; //green modify begin if (tmpFont.Size < 13) tmpFont = new Font(tmpFont.Name.ToString(), 13, FontStyle.Regular, GraphicsUnit.Point); //green end tmpSize = g.MeasureString(TheDataGridView.Columns[i].HeaderText, tmpFont); //green modify begin string colname = TheDataGridView.Columns[i].HeaderText; if (tmpSize.Width > tmpWidth) tmpWidth = tmpSize.Width;//获取datagridview的列宽 //green end RowHeaderHeight = tmpSize.Height;//获取表头高度 //green add begin //if (RowHeaderHeight < minheight) //RowHeaderHeight = minheight; //green end for (int j = 0; j < TheDataGridView.Rows.Count; j++) { tmpFont = TheDataGridView.Rows[j].DefaultCellStyle.Font; if (tmpFont == null) // If the there is no special font style of the CurrentRow, then use the default one associated with the DataGridView control tmpFont = TheDataGridView.DefaultCellStyle.Font; //green modify begin if (tmpFont.Size < 12) { tmpFont = new Font(tmpFont.Name.ToString(), 12, FontStyle.Regular, GraphicsUnit.Point); } //green end tmpSize = g.MeasureString("Anything", tmpFont); RowsHeight.Add(tmpSize.Height); tmpSize = g.MeasureString(TheDataGridView.Rows[j].Cells[i].EditedFormattedValue.ToString(), tmpFont); if (tmpSize.Width > tmpWidth) tmpWidth = tmpSize.Width; //green modify begin //if (tmpSize.Width < minwidth) // tmpWidth = minwidth; //if (tmpSize.Height < minheight) // tmpSize.Height = minheight; //green end } if (TheDataGridView.Columns[i].Visible) { TheDataGridViewWidth += tmpWidth; } //TheDataGridViewWidth = totalwidth / cols; //tmpWidth = 88; tmpWidth = intergered(tmpWidth); ColumnsWidth.Add(tmpWidth); } // Define the start/stop column points based on the page width and the DataGridView Width // We will use this to determine the columns which are drawn on each page and how wrapping will be handled // By default, the wrapping will occurr such that the maximum number of columns for a page will be determine int k; int mStartPoint = 0; for (k = 0; k < TheDataGridView.Columns.Count; k++) if (TheDataGridView.Columns[k].Visible) { mStartPoint = k; break; } int mEndPoint = TheDataGridView.Columns.Count; for (k = TheDataGridView.Columns.Count - 1; k >= 0; k--) if (TheDataGridView.Columns[k].Visible) { mEndPoint = k + 1; break; } float mTempWidth = TheDataGridViewWidth; float mTempPrintArea = (float)PageWidth - (float)LeftMargin - (float)RightMargin; // We only care about handling where the total datagridview width is bigger then the print area if (TheDataGridViewWidth > mTempPrintArea) { mTempWidth = 0.0F; for (k = 0; k < TheDataGridView.Columns.Count; k++) { if (TheDataGridView.Columns[k].Visible) { mTempWidth += ColumnsWidth[k]; // If the width is bigger than the page area, then define a new column print range if (mTempWidth > mTempPrintArea) { mTempWidth -= ColumnsWidth[k]; mColumnPoints.Add(new int[] { mStartPoint, mEndPoint }); mColumnPointsWidth.Add(mTempWidth); mStartPoint = k; mTempWidth = ColumnsWidth[k]; } } // Our end point is actually one index above the current index mEndPoint = k + 1; } } // Add the last set of columns mColumnPoints.Add(new int[] { mStartPoint, mEndPoint }); mColumnPointsWidth.Add(mTempWidth); mColumnPoint = 0; } } // The funtion that print the title, page number, and the header row private void DrawHeader(Graphics g) { CurrentY = (float)TopMargin; // Printing the page number (if isWithPaging is set to true) if (IsWithPaging) { if (flag > 2 && hasmorepages == false) { PageNumber = 0; lastnumber = 0; } if (lastnumber == mColumnPoint) { PageNumber++; } else { PageNumber = 1; lastnumber = mColumnPoint; } PageNumberson = mColumnPoint + 1; string PageString = "页号: " + PageNumber.ToString()+"-"+PageNumberson.ToString(); StringFormat PageStringFormat = new StringFormat(); PageStringFormat.Trimming = StringTrimming.Word; PageStringFormat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit | StringFormatFlags.NoClip; PageStringFormat.Alignment = StringAlignment.Far; Font PageStringFont = new Font("Tahoma", 8, FontStyle.Regular, GraphicsUnit.Point); RectangleF PageStringRectangle = new RectangleF((float)LeftMargin, CurrentY, (float)PageWidth - (float)RightMargin - (float)LeftMargin, g.MeasureString(PageString, PageStringFont).Height); g.DrawString(PageString, PageStringFont, new SolidBrush(Color.Black), PageStringRectangle, PageStringFormat); string printtime = "打印日期: " + DateTime.Now.Year.ToString() + "." + DateTime.Now.Month.ToString() + "." + DateTime.Now.Day.ToString(); StringFormat PrintTimeFormat = new StringFormat(); PrintTimeFormat.Trimming = StringTrimming.Word; PrintTimeFormat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit | StringFormatFlags.NoClip; PrintTimeFormat.Alignment = StringAlignment.Near; //Font PageStringFont = new Font("Tahoma", 8, FontStyle.Regular, GraphicsUnit.Point); g.DrawString(printtime, PageStringFont, new SolidBrush(Color.Black), PageStringRectangle, PrintTimeFormat); CurrentY += g.MeasureString(PageString, PageStringFont).Height; } // Printing the title (if IsWithTitle is set to true) if (IsWithTitle) { StringFormat TitleFormat = new StringFormat(); TitleFormat.Trimming = StringTrimming.Word; TitleFormat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit | StringFormatFlags.NoClip; if (IsCenterOnPage) TitleFormat.Alignment = StringAlignment.Center; else TitleFormat.Alignment = StringAlignment.Near; //green modify begin modify the font if (TheTitleFont.Size < 13) { TheTitleFont = new Font(TheTitleFont.Name.ToString(), 13, FontStyle.Bold, GraphicsUnit.Point); } //green end RectangleF TitleRectangle = new RectangleF((float)LeftMargin, CurrentY, (float)PageWidth - (float)RightMargin - (float)LeftMargin, g.MeasureString(TheTitleText, TheTitleFont).Height); g.DrawString(TheTitleText, TheTitleFont, new SolidBrush(TheTitleColor), TitleRectangle, TitleFormat); CurrentY += g.MeasureString(TheTitleText, TheTitleFont).Height; RectangleF TitleRectangleTwo = new RectangleF((float)LeftMargin, CurrentY, (float)PageWidth - (float)RightMargin - (float)LeftMargin, g.MeasureString(TheTitleTextTwo, TheTitleFontTwo).Height); g.DrawString(TheTitleTextTwo, TheTitleFontTwo, new SolidBrush(TheTitleColor), TitleRectangleTwo, TitleFormat); CurrentY += g.MeasureString(TheTitleTextTwo, TheTitleFontTwo).Height; } // Calculating the starting x coordinate that the printing process will start from float CurrentX = (float)LeftMargin; if (IsCenterOnPage) CurrentX += (((float)PageWidth - (float)RightMargin - (float)LeftMargin) - mColumnPointsWidth[mColumnPoint]) / 2.0F; // Setting the HeaderFore style Color HeaderForeColor = TheDataGridView.ColumnHeadersDefaultCellStyle.ForeColor; if (HeaderForeColor.IsEmpty) // If there is no special HeaderFore style, then use the default DataGridView style HeaderForeColor = TheDataGridView.DefaultCellStyle.ForeColor; SolidBrush HeaderForeBrush = new SolidBrush(HeaderForeColor); // Setting the HeaderBack style Color HeaderBackColor = TheDataGridView.ColumnHeadersDefaultCellStyle.BackColor; if (HeaderBackColor.IsEmpty) // If there is no special HeaderBack style, then use the default DataGridView style HeaderBackColor = TheDataGridView.DefaultCellStyle.BackColor; SolidBrush HeaderBackBrush = new SolidBrush(HeaderBackColor); // Setting the LinePen that will be used to draw lines and rectangles (derived from the GridColor property of the DataGridView control) Pen TheLinePen = new Pen(TheDataGridView.GridColor, 1); // Setting the HeaderFont style Font HeaderFont = TheDataGridView.ColumnHeadersDefaultCellStyle.Font; if (HeaderFont == null) // If there is no special HeaderFont style, then use the default DataGridView font style HeaderFont = TheDataGridView.DefaultCellStyle.Font; //green modify begin if (HeaderFont.Size < 13) { HeaderFont = new Font(HeaderFont.Name.ToString(), 13, FontStyle.Bold, GraphicsUnit.Point); } //green end // Calculating and drawing the HeaderBounds RectangleF HeaderBounds = new RectangleF(CurrentX, CurrentY, mColumnPointsWidth[mColumnPoint], RowHeaderHeight); g.FillRectangle(HeaderBackBrush, HeaderBounds); // Setting the format that will be used to print each cell of the header row StringFormat CellFormat = new StringFormat(); CellFormat.Trimming = StringTrimming.Word; CellFormat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit | StringFormatFlags.NoClip; // Printing each visible cell of the header row RectangleF CellBounds; float ColumnWidth; for (int i = (int)mColumnPoints[mColumnPoint].GetValue(0); i < (int)mColumnPoints[mColumnPoint].GetValue(1); i++) { if (!TheDataGridView.Columns[i].Visible) continue; // If the column is not visible then ignore this iteration ColumnWidth = ColumnsWidth[i]; // Check the CurrentCell alignment and apply it to the CellFormat //标题居中 //if (TheDataGridView.ColumnHeadersDefaultCellStyle.Alignment.ToString().Contains("Right")) // CellFormat.Alignment = StringAlignment.Far; //else if (TheDataGridView.ColumnHeadersDefaultCellStyle.Alignment.ToString().Contains("Center")) CellFormat.Alignment = StringAlignment.Center; //else // CellFormat.Alignment = StringAlignment.Near; CellBounds = new RectangleF(CurrentX, CurrentY, ColumnWidth, RowHeaderHeight); // Printing the cell text g.DrawString(TheDataGridView.Columns[i].HeaderText, HeaderFont, HeaderForeBrush, CellBounds, CellFormat); // Drawing the cell bounds if (TheDataGridView.RowHeadersBorderStyle != DataGridViewHeaderBorderStyle.None) // Draw the cell border only if the HeaderBorderStyle is not None g.DrawRectangle(TheLinePen, CurrentX, CurrentY, ColumnWidth, RowHeaderHeight); CurrentX += ColumnWidth; } CurrentY += RowHeaderHeight; } // The function that print a bunch of rows that fit in one page // When it returns true, meaning that there are more rows still not printed, so another PagePrint action is required // 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 private bool DrawRows(Graphics g) { //string ali;//对齐格式 // Setting the LinePen that will be used to draw lines and rectangles (derived from the GridColor property of the DataGridView control) Pen TheLinePen = new Pen(TheDataGridView.GridColor, 1); // The style paramters that will be used to print each cell Font RowFont; Color RowForeColor; Color RowBackColor; SolidBrush RowForeBrush; SolidBrush RowBackBrush; SolidBrush RowAlternatingBackBrush; // Setting the format that will be used to print each cell StringFormat CellFormat = new StringFormat(); CellFormat.Trimming = StringTrimming.Word; CellFormat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit; // Printing each visible cell RectangleF RowBounds; float CurrentX; float ColumnWidth; while (CurrentRow < TheDataGridView.Rows.Count-1) { if (TheDataGridView.Rows[CurrentRow].Visible) // Print the cells of the CurrentRow only if that row is visible { // Setting the row font style RowFont = TheDataGridView.Rows[CurrentRow].DefaultCellStyle.Font; if (RowFont == null) // If the there is no special font style of the CurrentRow, then use the default one associated with the DataGridView control RowFont = TheDataGridView.DefaultCellStyle.Font; //green modify begin if(RowFont.Size<12) { RowFont = new Font(RowFont.Name.ToString(), 12, FontStyle.Regular, GraphicsUnit.Point); } //green end // Setting the RowFore style RowForeColor = TheDataGridView.Rows[CurrentRow].DefaultCellStyle.ForeColor; if (RowForeColor.IsEmpty) // If the there is no special RowFore style of the CurrentRow, then use the default one associated with the DataGridView control RowForeColor = TheDataGridView.DefaultCellStyle.ForeColor; RowForeBrush = new SolidBrush(RowForeColor); // Setting the RowBack (for even rows) and the RowAlternatingBack (for odd rows) styles RowBackColor = TheDataGridView.Rows[CurrentRow].DefaultCellStyle.BackColor; if (RowBackColor.IsEmpty) // If the there is no special RowBack style of the CurrentRow, then use the default one associated with the DataGridView control { RowBackBrush = new SolidBrush(TheDataGridView.DefaultCellStyle.BackColor); RowAlternatingBackBrush = new SolidBrush(TheDataGridView.AlternatingRowsDefaultCellStyle.BackColor); } else // If the there is a special RowBack style of the CurrentRow, then use it for both the RowBack and the RowAlternatingBack styles { RowBackBrush = new SolidBrush(RowBackColor); RowAlternatingBackBrush = new SolidBrush(RowBackColor); } // Calculating the starting x coordinate that the printing process will start from CurrentX = (float)LeftMargin; if (IsCenterOnPage) CurrentX += (((float)PageWidth - (float)RightMargin - (float)LeftMargin) - mColumnPointsWidth[mColumnPoint]) / 2.0F; // Calculating the entire CurrentRow bounds RowBounds = new RectangleF(CurrentX, CurrentY, mColumnPointsWidth[mColumnPoint], RowsHeight[CurrentRow]); // Filling the back of the CurrentRow if (CurrentRow % 2 == 0) g.FillRectangle(RowBackBrush, RowBounds); else g.FillRectangle(RowAlternatingBackBrush, RowBounds); // Printing each visible cell of the CurrentRow for (int CurrentCell = (int)mColumnPoints[mColumnPoint].GetValue(0); CurrentCell < (int)mColumnPoints[mColumnPoint].GetValue(1); CurrentCell++) { if (!TheDataGridView.Columns[CurrentCell].Visible) continue; // If the cell is belong to invisible column, then ignore this iteration // Check the CurrentCell alignment and apply it to the CellFormat //if (TheDataGridView.Columns[CurrentCell].DefaultCellStyle.Alignment.ToString().Contains("Right")) //ali = TheDataGridView.Columns[CurrentCell].DefaultCellStyle.Alignment.ToString(); //if (TheDataGridView.Columns[CurrentCell].DefaultCellStyle.Alignment.ToString() == "MiddleRight") // CellFormat.Alignment = StringAlignment.Far; //else if (TheDataGridView.Columns[CurrentCell].DefaultCellStyle.Alignment.ToString().Contains("Center")) // CellFormat.Alignment = StringAlignment.Center; //else // CellFormat.Alignment = StringAlignment.Near; //string type = TheDataGridView.Columns[CurrentCell].DefaultCellStyle.Alignment.ToString; if (TheDataGridView.Columns[CurrentCell].ValueType.ToString() == "System.Single" || TheDataGridView.Columns[CurrentCell].ValueType.ToString() == "System.Double") CellFormat.Alignment = StringAlignment.Far; else CellFormat.Alignment = StringAlignment.Near; ColumnWidth = ColumnsWidth[CurrentCell]; RectangleF CellBounds = new RectangleF(CurrentX, CurrentY, ColumnWidth, RowsHeight[CurrentRow]); // Printing the cell text g.DrawString(TheDataGridView.Rows[CurrentRow].Cells[CurrentCell].EditedFormattedValue.ToString(), RowFont, RowForeBrush, CellBounds, CellFormat); // Drawing the cell bounds if (TheDataGridView.CellBorderStyle != DataGridViewCellBorderStyle.None) // Draw the cell border only if the CellBorderStyle is not None g.DrawRectangle(TheLinePen, CurrentX, CurrentY, ColumnWidth, RowsHeight[CurrentRow]); CurrentX += ColumnWidth; } CurrentY += RowsHeight[CurrentRow]; // Checking if the CurrentY is exceeds the page boundries // If so then exit the function and returning true meaning another PagePrint action is required if ((int)CurrentY > (PageHeight - TopMargin - BottomMargin)) { CurrentRow++; return true; } } CurrentRow++; } CurrentRow = 0;//why excute the word and then jump to DrawHeader() mColumnPoint++; // Continue to print the next group of columns if (mColumnPoint == mColumnPoints.Count) // Which means all columns are printed { mColumnPoint = 0; return false; } else return true; } // The method that calls all other functions public bool DrawDataGridView(Graphics g) { try { //if (flag < 3) //{ Calculate(g); //} DrawHeader(g); //DrawHeader(g); bool bContinue = DrawRows(g); return bContinue; } catch (Exception ex) { MessageBox.Show("Operation failed: " + ex.Message.ToString(), Application.ProductName + " - Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } } }
相关文章推荐
- c#asp.net表格Html数据模板转换Pdf文件web打印pdf报表dll
- vs2010 asp.net webForm Html表格数据模板转换pdf文件,web打印Pdf
- 开源:VS.NET打印思想与2003/5DataGrid、DataGridView及二维数据如ListView等终极打印实现(转)
- 【C#.NET】dataGridView查询SQL数据方法
- C#.NET自定义报表数据打印
- C#.NET常见问题(FAQ)-如何使用DataGridView跟Excel数据交互
- c#.net循环将DataGridView中的数据赋值到Excel中,并设置样式
- VS.NET打印思想与2003/5DataGrid、DataGridView及二维数据如ListView等终极打印实现
- C#打印DataGridView数据
- 开源:VS.NET打印思想与2003/5DataGrid、DataGridView及二维数据如ListView等终极打印实现
- C#打印DataGridView 中的数据
- VS.NET打印思想与2003/5DataGrid、DataGridView及二维数据如ListView等终极打印实现(全部源码)
- C#.NET自定义报表数据打印
- C#.NET自定义报表数据打印
- 开源:VS.NET打印思想与2003/5DataGrid、DataGridView及二维数据如ListView等终极打印实现(全部源码)
- C#读取Excel表格数据到DataGridView中和导出DataGridView中的数据到Excel
- vb.net2005 读取 excel 表格数据 填充 datagridview
- asp.net(c#)打印excel大数据量,最简单,最快的办法,个人认为,哈哈,有人会说,用gridview打印excel不是很方便吗?但是我发现数据量一大gridview就不行,速度慢不说,还会出错
- vb.net的datagridview如何让表格根据表格数据来改变颜色,如值为1时表格为红色,2时为蓝色
- 如何在C#中实现DATAGRIDVIEW 数据打印