Winform 实现DataGridView自定义多维表头打印+自定义列宽+一维表头自定义换行

    哈哈,小弟不才,在前辈大牛的基础上做了多维表头打印,代码粗糙,凑合用,有时间再做优化!

public class PrintClass

    {
        #region  全局变量
        private Dictionary> dicMoreHead = new Dictionary>();
        private Dictionary dicCelWidth;
        private string wLineStr = "\n";
        private DataGridView datagrid;
        private PrintDocument printdocument;
        private PageSetupDialog pagesetupdialog;
        private PrintPreviewDialog printpreviewdialog;
        private string title = "";//标题
        private string sPrintTime = "";//打印时间


        int currentpageindex = 0;//当前页的编号
        int rowcount = 0;//数据的行数
        int pagecount = 0;//打印页数
        int titlesize = 16;//标题的大小
        int xoffset = 0;//标题位置
        public int x = 0;//z绘画时的x轴位置
        public int PrintPageHeight = 1169;//打印的默认高度
        public int PrintPageWidth = 827;//打印的默认宽度
        public bool iseverypageprinttitle = false;//是否每一页都要打印标题
        public int headerheight = 30;//标题高度
        public int topmargin = 60; //顶边距 
        public int celltopmargin = 6;//单元格顶边距 
        public int cellleftmargin = 4;//单元格左边距 
        public int pagerowcount = 7;//每页行数 
        public int rowgap = 23;//行高 
        public int colgap = 5;//每列间隔 
        public int leftmargin = 50;//左边距 
        public Font titlefont = new Font("arial", 14);//标题字体 
        public Font font = new Font("arial", 10);//正文字体


        public Font footerfont = new Font("arial", 8);//页脚显示页数的字体
        public Font uplinefont = new Font("arial", 9, FontStyle.Bold);//当header分两行显示的时候,上行显示的字体
        public Font underlinefont = new Font("arial", 8);//当header分两行显示的时候,下行显示的字体
        public Brush brush = new SolidBrush(Color.Black);//画刷
        public Font headerfont = new Font("arial", 9, FontStyle.Bold);//列名标题字体
        public Brush brushHeaderFont = new SolidBrush(Color.Black);//列名字体画刷
        public Brush brushHeaderBack = new SolidBrush(Color.White);//列名背景画刷
        public Font Cellfont = new Font("arial", 9);//单元格字体
        public Brush brushCellFont = new SolidBrush(Color.Black);//单元格字体画刷
        public Brush brushCellBack = new SolidBrush(Color.White);//单元格背景画刷
        public bool isautopagerowcount = true;//是否自动计算行数
        public int buttommargin = 80;//底边距 
        public bool needprintpageindex = true;//是否打印页脚页数 
        public Color LineColor = Color.Black;//线的颜色
        public bool LineUP = true;//上边线
        public bool LineLeft = true;//左边线
        public bool LineUnit = true;//单元格的线
        public bool Boundary = false;//下边线


        public int AlignmentSgin = -1;//对齐方式的标识
        public int HAlignment = 0;//标题对齐方式
        public int UAlignment = 0;//单元格对齐方式
        public int LeftAlignment = 50;//左对齐的边界
        public int RightAlignment = 50;//右对齐的边界
        public int CenterAlignment = 0;//居中对齐边界
        public bool PageAspect = false;//打印的方向
        public static bool PageScape = false;//打印方向
        public int PageSheet = 0;
        /// 
        /// 自定义列宽
        /// 
        public Dictionary DicCelWidth { get => dicCelWidth; set => dicCelWidth = value; }


        /// 
        /// 自定义多维表头
        /// 
        public Dictionary> DicMoreHead { get => dicMoreHead; set => dicMoreHead = value; }


        /// 
        /// 自定义换行符
        /// 
        public string WLineStr { get => wLineStr; set => wLineStr = value; }
        #endregion


        #region  打印信息的初始化
        /// 
        /// 打印信息的初始化
        /// 
        /// 打印数据
        /// 打印标题
        /// 标题大小
        /// 纸张大小
        /// 是否横向打印
        /// 返回DataSet对象
        public PrintClass(DataGridView datagrid, string title, int titlesize, int PageS, bool lendscape)
        {
            this.title = title;//设置标题的名称
            this.titlesize = titlesize;//设置标题的大小
            this.datagrid = datagrid;//获取打印数所据
            this.PageSheet = PageS;//纸张大小
            printdocument = new PrintDocument();//实例化PrintDocument类
            pagesetupdialog = new PageSetupDialog();//实例化PageSetupDialog类
            pagesetupdialog.Document = printdocument;//获取当前页的设置
            printpreviewdialog = new PrintPreviewDialog();//实例化PrintPreviewDialog类
            printpreviewdialog.Document = printdocument;//获取预览文档的信息
            printpreviewdialog.FormBorderStyle = FormBorderStyle.Fixed3D;//设置窗体的边框样式


            //横向打印的设置
            if (PageSheet >= 0)
            {
                if (lendscape == true)
                {
                    printdocument.DefaultPageSettings.Landscape = lendscape;//横向打印
                }
                else
                {
                    printdocument.DefaultPageSettings.Landscape = lendscape;//纵向打印
                }
            }
            pagesetupdialog.Document = printdocument;
            //MessageBox.Show(printdocument.DefaultPageSettings.Landscape.ToString());
            printdocument.PrintPage += new PrintPageEventHandler(this.printdocument_printpage);//事件的重载
        }


        /// 
        /// 重载实例化打印类
        /// 
        /// 
        /// 
        /// 
        /// 
        public PrintClass(DataGridView datagrid, string title, string sPrinterName = "", string sPrintTime = "", bool lendscape = false)
        {
            PageScape = lendscape;
            this.title = title;//设置标题的名称
            this.sPrintTime = sPrintTime;//打印时间
            this.titlesize = 16;//设置标题的大小
            this.AlignmentSgin = 1;//居中对齐
            this.datagrid = datagrid;//获取打印数据
            //this.PageSheet = 0;//纸张大小A4
            printdocument = new PrintDocument();//实例化PrintDocument类
            pagesetupdialog = new PageSetupDialog();//实例化PageSetupDialog类
            pagesetupdialog.Document = printdocument;//获取当前页的设置
            printpreviewdialog = new PrintPreviewDialog();//实例化PrintPreviewDialog类
            printpreviewdialog.Document = printdocument;//获取预览文档的信息
            printpreviewdialog.FormBorderStyle = FormBorderStyle.Fixed3D;//设置窗体的边框样式
            if (!string.IsNullOrEmpty(sPrinterName))
            {
                printdocument.PrinterSettings.PrinterName = sPrinterName;//设置打印机
            }
            //横向打印的设置
            if (PageSheet >= 0)
            {
                if (lendscape == true)
                {
                    printdocument.DefaultPageSettings.Landscape = lendscape;//横向打印
                }
                else
                {
                    printdocument.DefaultPageSettings.Landscape = lendscape;//纵向打印
                }
            }
            pagesetupdialog.Document = printdocument;
            //MessageBox.Show(printdocument.DefaultPageSettings.Landscape.ToString());
            printdocument.PrintPage += new PrintPageEventHandler(this.printdocument_printpage);//事件的重载
        }
        #endregion


        #region  纸张大小的设置
        /// 
        ///  纸张大小的设置
        /// 
        /// 纸张大小的编号
        /// 返回string对象
        public string Page_Size(int n)
        {
            string pageN = "";//纸张的名称
            switch (n)
            {
                case 1: { pageN = "A5"; PrintPageWidth = 583; PrintPageHeight = 827; break; }
                case 2: { pageN = "A6"; PrintPageWidth = 413; PrintPageHeight = 583; break; }
                case 3: { pageN = "B5(ISO)"; PrintPageWidth = 693; PrintPageHeight = 984; break; }
                case 4: { pageN = "B5(JIS)"; PrintPageWidth = 717; PrintPageHeight = 1012; break; }
                case 5: { pageN = "Double Post Card"; PrintPageWidth = 583; PrintPageHeight = 787; break; }
                case 6: { pageN = "Envelope #10"; PrintPageWidth = 412; PrintPageHeight = 950; break; }
                case 7: { pageN = "Envelope B5"; PrintPageWidth = 693; PrintPageHeight = 984; break; }
                case 8: { pageN = "Envelope C5"; PrintPageWidth = 638; PrintPageHeight = 902; break; }
                case 9: { pageN = "Envelope DL"; PrintPageWidth = 433; PrintPageHeight = 866; break; }
                case 10: { pageN = "Envelope Monarch"; PrintPageWidth = 387; PrintPageHeight = 750; break; }
                case 11: { pageN = "ExeCutive"; PrintPageWidth = 725; PrintPageHeight = 1015; break; }
                case 12: { pageN = "Legal"; PrintPageWidth = 850; PrintPageHeight = 1400; break; }
                case 13: { pageN = "Letter"; PrintPageWidth = 850; PrintPageHeight = 1100; break; }
                case 14: { pageN = "Post Card"; PrintPageWidth = 394; PrintPageHeight = 583; break; }
                case 15: { pageN = "16K"; PrintPageWidth = 775; PrintPageHeight = 1075; break; }
                case 16: { pageN = "8.5x13"; PrintPageWidth = 850; PrintPageHeight = 1300; break; }
            }
            return pageN;//返回纸张的名
        }
        #endregion


        #region  页边距的设置
        /// 
        ///  页边距的设置
        /// 
        /// 边距信息
        public void PrintSetUp(string[] SetUp1)
        {
            if (SetUp1[0] == "true")
            {
                topmargin = Int32.Parse(SetUp1[1]);//顶边距
                leftmargin = Int32.Parse(SetUp1[2]);//左边距
                buttommargin = Int32.Parse(SetUp1[3]);//底边距
                AlignmentSgin = -1;//设置对齐方式的标识
            }
        }
        #endregion


        #region  文字的位置
        /// 
        ///  文字的位置
        /// 
        /// 单元格的宽度
        /// 文字的宽度
        /// 单元格的左边距
        /// 对齐方式
        /// 返回int对象
        private int Alignment_Mode(int CellW, int StrW, int colW, int Ali)
        {
            int ALiW = 0;
            switch (Ali)
            {
                case 0://左对齐
                    {
                        ALiW = colW; //设置文字的左端位置
                        break;
                    }
                case 1://局中
                    {
                        ALiW = (int)((CellW - StrW) / 2);//设置文字的左端位置
                        break;
                    }
                case 2://右对齐
                    {
                        ALiW = CellW - StrW - colW;//设置文字的左端位置
                        break;
                    }
            }
            return ALiW;
        }
        #endregion


        #region  页的打印事件
        /// 
        ///  页的打印事件(主要用于绘制打印报表)
        /// 
        private void printdocument_printpage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            #region 一维表头换行 若想实现多维表头+内容行的换行请遍历多维表头以及内容行:换行的个数*count,注意:对应遍历画线的地方也要做相应的修改
            string str = wLineStr;
            int count = 0;
            for (int i = 0; i < datagrid.ColumnCount; i++)
            {
                string cellvalueTemp = string.Empty;
                if (str == "'\r'" || str == "'\n'")
                {
                    cellvalueTemp = datagrid.Columns[i].HeaderText;
                }
                else
                {
                    cellvalueTemp = datagrid.Columns[i].HeaderText.Replace(str, "\n" + str);
                }
                if (cellvalueTemp.Contains('\r') || cellvalueTemp.Contains('\n'))
                {
                    count = rowgap * (cellvalueTemp.Split(new char[] { '\r', '\n' }).Length - 1) - 15;//单元格信息的Y坐标
                }
            }
            #endregion


            int iHeadHeight = this.headerheight;
            iHeadHeight = this.headerheight * (dicMoreHead.Count + 1) + count;


            PrintPageWidth = e.PageBounds.Width;//获取打印线张的宽度
            PrintPageHeight = e.PageBounds.Height;//获取打印线张的高度
            if (this.isautopagerowcount)//自动计算页的行数
                pagerowcount = (int)((PrintPageHeight - this.topmargin - titlesize - this.headerfont.Height - iHeadHeight - this.buttommargin) / this.rowgap);//获取每页的行数
            pagecount = (int)(rowcount / pagerowcount);//获取打印多少页
            pagesetupdialog.AllowOrientation = true;//启动打印页面对话框的方向部分
            if (rowcount % pagerowcount > 0)//如果数据的行数大于页的行数
                pagecount++;//页数加1
            int colcount = 0;//记录数据的列数
            int y = topmargin;//获取表格的顶边距
            string cellvalue = "";//记录文本信息(列标题和单元格的文本信息)
            int startrow = currentpageindex * pagerowcount;//设置打印的初始页数
            int endrow = startrow + this.pagerowcount < rowcount ? startrow + pagerowcount : rowcount;//设置打印的最大页数
            int currentpagerowcount = endrow - startrow;//获取打印页数
            colcount = datagrid.ColumnCount;//获取打印数据的列数
            x = leftmargin;//获取表格的左边距


            #region 处理列宽
            Dictionary dicCelWd = new Dictionary();
            //默认列宽
            for (int j = 0; j < colcount; j++)
            {
                dicCelWd.Add(j, (int)datagrid.Columns[j].FillWeight);
            }
            //存在自定义列宽时
            if (dicCelWidth != null)
            {
                foreach (int skeys in dicCelWidth.Keys)
                {
                    dicCelWd[skeys] = dicCelWidth[skeys];
                }
            }
            #endregion


            //设置绘置背景颜色的点
            Point headup, headdown;
            //获取报表的宽度
            int cwidth = 0;
            for (int j = 0; j < colcount; j++)//循环数据的列数
            {
                if (dicCelWd[j] > 0)//如果列的宽大于0
                {
                    cwidth += dicCelWd[j] + colgap;//累加每列的宽度
                }
            }


            if (AlignmentSgin >= -1)//设置对齐方式的边界位置
            {
                int tn = (int)(e.Graphics.MeasureString(this.title, this.titlefont).Width);//获取标题的宽度
                switch (AlignmentSgin)//对齐方式
                {
                    case 0://左对齐
                        {
                            x = LeftAlignment;//获取左对齐的默认边界
                            leftmargin = x;//设置左边距
                            if (tn > cwidth)//如果标题的宽度大于表格的宽度
                                xoffset = leftmargin;//标题的左边距为表格的左边距
                            else
                                xoffset = (int)(PrintPageWidth - (PrintPageWidth - 50) + (cwidth - tn) / 2);//使标题局中
                            break;
                        }
                    case 1://局中
                        {
                            x = (PrintPageWidth - cwidth) / 2;//设置表格的局中位置
                            leftmargin = x;//设置左边距
                            xoffset = (int)((PrintPageWidth - tn) / 2);//标题相对于表格局中
                            break;
                        }
                    case 2://右对齐
                        {
                            x = PrintPageWidth - cwidth - RightAlignment;//设置表格右对齐的左边距位置
                            leftmargin = x;//设置左边距
                            if (tn > cwidth)//如果标题的宽度大于表格的宽度
                                xoffset = (int)(PrintPageWidth - tn);//使标题的右边距与表格的右边距相同
                            else
                                xoffset = (int)(PrintPageWidth - 50 - cwidth + (cwidth - tn) / 2);//标题相对于表格局中
                            break;
                        }
                    case -1://标题的默认状态
                        {
                            if (tn > cwidth)//如果标题的宽度大于表格的宽度
                            {
                                if ((tn - cwidth) / 2 < leftmargin)//标题在表格上局中,左边的超出的部分小于左边距
                                    xoffset = (int)(leftmargin - (tn - cwidth) / 2);//使标题相对于表格局中
                                else
                                    xoffset = leftmargin;//使标题的左边距与表格的左边距相同
                            }
                            else
                                xoffset = (int)(x + (cwidth - tn) / 2);//标题相对于表格局中
                            break;
                        }
                }
            }


            //绘置标题
            if (this.currentpageindex == 0 || this.iseverypageprinttitle)//当前页为首页,并且每页都要打印标题
            {
                e.Graphics.DrawString(this.title, titlefont, brush, xoffset, y);//绘制标题
                y += titlesize;//获取标题底端位置
            }
            //绘制打印时间
            if (!string.IsNullOrEmpty(this.sPrintTime))
            {
                y += (int)Cellfont.Size;
                e.Graphics.DrawString("打印时间:" + sPrintTime, Cellfont, brushHeaderFont, x, y + (rowgap - titlesize));
            }


            //绘制标题栏的背景颜色
            //这个Y是距离上面多少个表头的高度
            int iTemp = this.headerheight;
            y += iTemp;
            headup = new Point(x, y);//设置左上角位置
            headdown = new Point(cwidth, headerheight);//设置右下角位置
            drawrectangle(brushHeaderBack, headup, headdown, e.Graphics);//填充矩形框
            //绘制单元格的背景颜色
            headup = new Point(x, y + headerheight);//设置左上角位置
            headdown = new Point(cwidth, (endrow - startrow) * rowgap);//设置右下角位置
            drawrectangle(brushCellBack, headup, headdown, e.Graphics);//填充矩形框
            if (LineLeft == true)//如果是左边线,画出打印表格最左边的竖线
                drawline(new Point(x, y), new Point(x, y + currentpagerowcount * rowgap + iHeadHeight), e.Graphics, 0);//画线


            #region 多维表头
            foreach (int iskey in dicMoreHead.Keys)
            {
                int xN = x;
                int yN = y;
                int K = 0;
                foreach (MoreHead model in dicMoreHead[dicMoreHead.Count - 1 - iskey])
                {
                    int tempWd = 0;
                    for (int j = model.ICelStar; j <= model.ICelEnd; j++)//循环数据的列数
                    {
                        if (dicCelWd[j] > 0)//如果列的宽大于0
                        {
                            tempWd += dicCelWd[j] + colgap;//累加每列的宽度
                        }
                    }
                    if (tempWd > 0)//如果列的宽度大于0
                    {
                        cellvalue = model.SCelVule;//获取列标题
                        //绘制标题栏文字
                        int Ha = Alignment_Mode(tempWd, (int)(e.Graphics.MeasureString(cellvalue, Cellfont).Width), cellleftmargin, HAlignment);//设置列标题的位置
                        e.Graphics.DrawString(cellvalue, headerfont, brushHeaderFont, xN + Ha, yN + celltopmargin);//绘制列标题
                        xN += tempWd;//横向,下一个单元格的位置
                                   //右侧坚线
                        if (LineUnit == true)//如果是左边单元格的线
                            drawline(new Point(xN, yN), new Point(xN, yN + this.headerheight), e.Graphics, 0);//画线
                        if ((LineLeft == true) && (K == (colcount - 1)))//如果是最右边的线
                            drawline(new Point(xN, yN), new Point(xN, yN + this.headerheight), e.Graphics, 0);//画线
                        int nnp = yN + this.headerheight;//下一行线的位置
                    }
                    K++;
                }
                //列标题上边的线
                if (LineUP == true)
                    drawline(new Point(leftmargin, yN), new Point(xN, yN), e.Graphics, 0); //绘制最上面的线 
                y += this.headerheight;//设置下一个线的位置
            }
            #endregion


            //设置标题栏中的文字及坚线
            for (int j = 0; j < colcount; j++)//遍历列数据
            {
                int colwidth = dicCelWd[j];//获取列的宽度
                if (colwidth > 0)//如果列的宽度大于0
                {
                    cellvalue = datagrid.Columns[j].HeaderText.Replace(str, "\n" + str);//获取列标题
                    //绘制标题栏文字
                    int Ha = Alignment_Mode(dicCelWd[j], (int)(e.Graphics.MeasureString(cellvalue, Cellfont).Width), cellleftmargin, HAlignment);//设置列标题的位置
                    e.Graphics.DrawString(cellvalue, headerfont, brushHeaderFont, x + Ha, y + celltopmargin);//绘制列标题
                    x += colwidth + colgap;//横向,下一个单元格的位置
                    //右侧坚线
                    if (LineUnit == true)//如果是左边单元格的线
                        drawline(new Point(x, y), new Point(x, y + currentpagerowcount * rowgap + this.headerheight + count), e.Graphics, 0);//画线
                    if ((LineLeft == true) && (j == (colcount - 1)))//如果是最右边的线
                        drawline(new Point(x, y), new Point(x, y + currentpagerowcount * rowgap + this.headerheight + count), e.Graphics, 0);//画线
                    int nnp = y + currentpagerowcount * rowgap + this.headerheight;//下一行线的位置
                }
            }


            int rightbound = x;
            //列标题上边的线
            if (LineUP == true)
                drawline(new Point(leftmargin, y), new Point(rightbound, y), e.Graphics, 0); //绘制最上面的线 
            headup = new Point(leftmargin, y);
            y += this.headerheight + count;//设置下一个线的位置
            //打印所有的行信息
            for (int i = startrow; i < endrow; i++) //对行进行循环
            {
                x = leftmargin;//获取线的X坐标点
                for (int j = 0; j < colcount; j++)//对列进行循环
                {
                    if (dicCelWd[j] > 0)//如果列的宽度大于0
                    {
                        cellvalue = datagrid.Rows[i].Cells[j].FormattedValue.ToString();//获取单元格的值
                        //绘制单元格中的信息
                        int Ua = Alignment_Mode(dicCelWd[j], (int)(e.Graphics.MeasureString(cellvalue, Cellfont).Width), cellleftmargin, UAlignment);
                        e.Graphics.DrawString(cellvalue, Cellfont, brushHeaderFont, x + Ua, y + celltopmargin);//绘制单元格信息
                        x += dicCelWd[j] + colgap;//单元格信息的X坐标
                        y = y + rowgap * (cellvalue.Split(new char[] { '\r', '\n' }).Length - 1);//单元格信息的Y坐标
                    }
                }
                //单元格上边的线
                if (LineUnit == true)
                    drawline(new Point(leftmargin, y), new Point(rightbound, y), e.Graphics, 0);
                if (Boundary == true && i == startrow)//绘制分割线
                    drawline(new Point(leftmargin, y), new Point(rightbound, y), e.Graphics, 1);
                y += rowgap;//设置下行的位置
            }
            //表格最下面的边线
            if (LineUP == true)
                drawline(new Point(leftmargin, y), new Point(rightbound, y), e.Graphics, 0);//绘制最下面的线
            currentpageindex++;//下一页的页码
            if (this.needprintpageindex)//如果显示页脚
                e.Graphics.DrawString("共 " + pagecount.ToString() + " 页   第 " + this.currentpageindex.ToString() + " 页", this.footerfont, brush, PrintPageWidth - 200, (int)(PrintPageHeight - this.buttommargin / 2 - this.footerfont.Height));//绘制页脚信息
            if (currentpageindex < pagecount)//如果当前页不是最后一页
            {
                e.HasMorePages = true;//打印副页
            }
            else
            {
                e.HasMorePages = false;//不打印副页
                this.currentpageindex = 0;//当前打印的页编号设为0
            }
        }
        #endregion


        #region  绘制边线
        /// 
        ///  绘制边线
        /// 
        /// 左上角的坐标
        /// 右下角的坐标
        /// Graphics类
        /// 标识
        private void drawline(Point sp, Point ep, Graphics gp, int n)
        {
            int w = 1;//设置线的宽度
            if (n == 1)//如果是分割线
                w = 2;//设置线宽为2
            Pen pen = new Pen(LineColor, w);//设置画笔样式
            gp.DrawLine(pen, sp, ep);//绘制线
        }
        #endregion


        #region  绘制填充的矩形框
        /// 
        ///  绘制填充的矩形框
        /// 
        /// 画刷颜色
        /// 左上角的坐标
        /// 右下角的坐标
        /// Graphics类
        private void drawrectangle(Brush ColorB, Point P1, Point P2, Graphics gp)
        {
            gp.FillRectangle(ColorB, P1.X, P1.Y, P2.X, P2.Y);//填充一个矩形框
        }
        #endregion


        #region 显示打印预览窗体
        /// 
        ///  显示打印预览窗体
        /// 
        public void print()
        {


            rowcount = 0;//记录数据的行数
            string paperName = Page_Size(PageSheet);//获取当前纸张的大小
            PageSettings storePageSetting = new PageSettings();//实列化一个对PageSettings对象
            foreach (PaperSize ps in printdocument.PrinterSettings.PaperSizes)//查找当前设置纸张
                if (paperName == ps.PaperName)//如果找到当前纸张的名称
                {
                    storePageSetting.PaperSize = ps;//获取当前纸张的信息
                }
            printdocument.DefaultPageSettings.Landscape = PageScape;//设置横向打印






            if (PageScape)//如果是横向打印
            {
                storePageSetting.PaperSize = new PaperSize("Custom", PrintPageHeight, PrintPageWidth);//设置打印页的大小
            }
            else
            {
                storePageSetting.PaperSize = new PaperSize("Custom", PrintPageWidth, PrintPageHeight);//设置打印页的大小
            }








            //--pagesetupdialog.Document = printdocument;
            //printdocument.DefaultPageSettings = storePageSetting;//对打印机进行设置
            if (datagrid.DataSource.GetType().ToString() == "System.Data.DataTable")//判断数据类型
            {
                rowcount = ((DataTable)datagrid.DataSource).Rows.Count;//获取数据的行数
            }
            else if (datagrid.DataSource.GetType().ToString() == "System.Collections.ArrayList")//判断数据类型
            {
                rowcount = ((ArrayList)datagrid.DataSource).Count;//获取数据的行数
            }
            try
            {
                printdocument.DefaultPageSettings.Landscape = PageScape;//设置横向打印
                pagesetupdialog.Document = printdocument;
                (printpreviewdialog as Form).WindowState = FormWindowState.Maximized;//最大化
                printpreviewdialog.ShowDialog();//显示打印预览窗体
            }
            catch (Exception e)
            {
                throw new Exception("printer error." + e.Message);
            }
        }
        #endregion


    }


    public class MoreHead
    {
        private int iCelStar;
        private int iCelEnd;
        private string sCelVule;


        public int ICelStar { get => iCelStar; set => iCelStar = value; }
        public int ICelEnd { get => iCelEnd; set => iCelEnd = value; }
        public string SCelVule { get => sCelVule; set => sCelVule = value; }
    }


调用: 

if (gvApplyWeekWork.RowCount == 0) return;

            string sFileName = cmbYear.Text + "年" + cmbMonth.Text + "月";
            sFileName += gbApplyDocWork.Text;
            PrintClass pc = new PrintClass(gvApplyWeekWork, sFileName, RegistePara.ReportPrintName, Convert.ToDateTime(CommonHelper.GetServiceDateTime()).ToString("yyyy-MM-dd"), true);


            #region 构造多维打印
            Dictionary> dicMoreHe = new Dictionary>();
            List listModel = new List();
            listModel.Add(new MoreHead() { ICelStar = 0, ICelEnd = 0, SCelVule = "组织机构" });
            int nColFirst = 1;
            int nColLast = dic.Count;
            foreach (DataRow dr in dtGVHeard.Rows)
            {
                listModel.Add(new MoreHead() { ICelStar = nColFirst, ICelEnd = nColLast, SCelVule = Convert.ToString(dr[T_orderinfo.F_Examitemname]) });
                nColFirst += dic.Count;
                nColLast += dic.Count;
            }
            listModel.Add(new MoreHead() { ICelStar = dtGVHeard.Rows.Count * dic.Count + 1, ICelEnd = dtGVHeard.Rows.Count * dic.Count + 2, SCelVule = "总计" });
            dicMoreHe.Add(0, listModel);
            pc.DicMoreHead = dicMoreHe;


            Dictionary dicCelW = new Dictionary();
            for (int i = 0; i <= gvApplyWeekWork.ColumnCount - 1; i++)
            {
                if (i == 0)
                {
                    dicCelW.Add(i, 100);
                }
                else
                {
                    dicCelW.Add(i, 45);
                }
            }
            pc.DicCelWidth = dicCelW;


            pc.WLineStr = "[";
            #endregion
            pc.print();

效果:

Winform 实现DataGridView自定义多维表头打印+自定义列宽+一维表头自定义换行_第1张图片

你可能感兴趣的:(WinForm)