DataGridView合并单元格(多行多列合并)

一、点击在拖入的显示控件(TreeList)右上方的箭头,在Treelist任务中选择数据源,添加项目数据源,依次选择数据库、数据集,新建连接,浏览选择数据库(*.mdb),依次点击 下一步,选择“表”,完成。

二、具体代码如下:

        #region"合并单元格(多行多列)"

        //需要(行、列)合并的所有列标题名
        List<String> colsHeaderText_V = new List<String>();
        List<String> colsHeaderText_H = new List<String>();

        private void InitFormatColumns()
        {
            colsHeaderText_V.Add("PHONE1");
            colsHeaderText_V.Add("PHONE2");

            colsHeaderText_H.Add("IMAGEINDEX");
            colsHeaderText_H.Add("PARENTID");
            colsHeaderText_H.Add("DEPARTMENT");
            colsHeaderText_H.Add("LOCATION");
        }

        //绘制单元格
        private void dataGridView1_CellPainting(object sender, System.Windows.Forms.DataGridViewCellPaintingEventArgs e)
        {
            foreach (string fieldHeaderText in colsHeaderText_H)
            {
                //纵向合并
                if (e.ColumnIndex >= 0 && this.dataGridView1.Columns[e.ColumnIndex].HeaderText == fieldHeaderText && e.RowIndex >= 0)
                {
                    using (
                        Brush gridBrush = new SolidBrush(this.dataGridView1.GridColor),
                        backColorBrush = new SolidBrush(e.CellStyle.BackColor))
                    {
                        using (Pen gridLinePen = new Pen(gridBrush))
                        {
                            // 擦除原单元格背景
                            e.Graphics.FillRectangle(backColorBrush, e.CellBounds);

                            /****** 绘制单元格相互间隔的区分线条,datagridview自己会处理左侧和上边缘的线条,因此只需绘制下边框和和右边框
                             DataGridView控件绘制单元格时,不绘制左边框和上边框,共用左单元格的右边框,上一单元格的下边框*****/

                            //不是最后一行且单元格的值不为null
                            if (e.RowIndex < this.dataGridView1.RowCount - 1 && this.dataGridView1.Rows[e.RowIndex + 1].Cells[e.ColumnIndex].Value != null)
                            {
                                //若与下一单元格值不同
                                if (e.Value.ToString() != this.dataGridView1.Rows[e.RowIndex + 1].Cells[e.ColumnIndex].Value.ToString())
                                {
                                    //下边缘的线
                                    e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1,
                                    e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
                                    //绘制值
                                    if (e.Value != null)
                                    {
                                        e.Graphics.DrawString(e.Value.ToString(), e.CellStyle.Font,
                                            Brushes.Crimson, e.CellBounds.X + 2,
                                            e.CellBounds.Y + 2, StringFormat.GenericDefault);
                                    }
                                }
                                //若与下一单元格值相同
                                else
                                {
                                    //背景颜色
                                    //e.CellStyle.BackColor = Color.LightPink;   //仅在CellFormatting方法中可用
                                    this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Style.BackColor = Color.LightBlue;
                                    this.dataGridView1.Rows[e.RowIndex + 1].Cells[e.ColumnIndex].Style.BackColor = Color.LightBlue;
                                    //只读(以免双击单元格时显示值)
                                    this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].ReadOnly = true;
                                    this.dataGridView1.Rows[e.RowIndex + 1].Cells[e.ColumnIndex].ReadOnly = true;
                                }
                            }
                            //最后一行或单元格的值为null
                            else
                            {
                                //下边缘的线
                                e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1,
                                    e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);

                                //绘制值
                                if (e.Value != null)
                                {
                                    e.Graphics.DrawString(e.Value.ToString(), e.CellStyle.Font,
                                        Brushes.Crimson, e.CellBounds.X + 2,
                                        e.CellBounds.Y + 2, StringFormat.GenericDefault);
                                }
                            }

                            ////左侧的线()
                            //e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left,
                            //    e.CellBounds.Top, e.CellBounds.Left,
                            //    e.CellBounds.Bottom - 1);

                            //右侧的线
                            e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1,
                                e.CellBounds.Top, e.CellBounds.Right - 1,
                                e.CellBounds.Bottom - 1);

                            //设置处理事件完成(关键点),只有设置为ture,才能显示出想要的结果。
                            e.Handled = true;
                        }
                    }
                }
            }

            foreach (string fieldHeaderText in colsHeaderText_V)
            {
                //横向合并
                if (e.ColumnIndex >= 0 && this.dataGridView1.Columns[e.ColumnIndex].HeaderText == fieldHeaderText && e.RowIndex >= 0)
                {
                    using (
                        Brush gridBrush = new SolidBrush(this.dataGridView1.GridColor),
                        backColorBrush = new SolidBrush(e.CellStyle.BackColor))
                    {
                        using (Pen gridLinePen = new Pen(gridBrush))
                        {
                            // 擦除原单元格背景
                            e.Graphics.FillRectangle(backColorBrush, e.CellBounds);

                            /****** 绘制单元格相互间隔的区分线条,datagridview自己会处理左侧和上边缘的线条,因此只需绘制下边框和和右边框
                             DataGridView控件绘制单元格时,不绘制左边框和上边框,共用左单元格的右边框,上一单元格的下边框*****/

                            //不是最后一列且单元格的值不为null
                            if (e.ColumnIndex < this.dataGridView1.ColumnCount - 1 && this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex + 1].Value != null)
                            {
                                if (e.Value.ToString() != this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex + 1].Value.ToString())
                                {
                                    //右侧的线
                                    e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1, e.CellBounds.Top,
                                        e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
                                    //绘制值
                                    if (e.Value != null)
                                    {
                                        e.Graphics.DrawString(e.Value.ToString(), e.CellStyle.Font,
                                            Brushes.Crimson, e.CellBounds.X + 2,
                                            e.CellBounds.Y + 2, StringFormat.GenericDefault);
                                    }
                                }
                                //若与下一单元格值相同
                                else
                                {
                                    //背景颜色
                                    //e.CellStyle.BackColor = Color.LightPink;   //仅在CellFormatting方法中可用
                                    this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Style.BackColor = Color.LightPink;
                                    this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex + 1].Style.BackColor = Color.LightPink;
                                    //只读(以免双击单元格时显示值)
                                    this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].ReadOnly = true;
                                    this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex + 1].ReadOnly = true;
                                }
                            }
                            else
                            {
                                //右侧的线
                                e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1, e.CellBounds.Top,
                                    e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);

                                //绘制值
                                if (e.Value != null)
                                {
                                    e.Graphics.DrawString(e.Value.ToString(), e.CellStyle.Font,
                                        Brushes.Crimson, e.CellBounds.X + 2,
                                        e.CellBounds.Y + 2, StringFormat.GenericDefault);
                                }
                            }
                            //下边缘的线
                            e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1,
                                                        e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
                            e.Handled = true;
                        }
                    }

                }
            }

        }
        #endregion

  

时间: 2024-10-11 00:55:54

DataGridView合并单元格(多行多列合并)的相关文章

table合并单元格 colspan(跨列)和rowspan(跨行)

colspan和rowspan这两个属性用于创建特殊的表格. colspan是“column span(跨列)”的缩写.colspan属性用在td标签中,用来指定单元格横向跨越的列数: 在浏览器中将显示如下: 单元格1 单元格2 单元格3 单元格4 该例通过把colspan设为“3”, 令所在单元格横跨了三列.如果我们将colspan设为“2”,则该单元格将只跨越两列,于是有必要在第一行插入另外一个单元格,以确保两行占据相同的列数. 该例在浏览器中将显示如下: 单元格1 单元格2 单元格3 单元

vue中 表头 th 合并单元格,且表格列数不定的动态渲染方法

吐槽 今天,在vue中遇到 复杂表格的渲染 ,需要合并表头th的单元格,且合并单元格的那列的表头数据是动态数据,也就是不知道会有多少个表头列,而这几个表头列还分了好几个子表头. 这个需求在js里用Juicer模板很好做的,思路我是有的,但就是对于vue,我也算初学者,很多概念不是很懂,这就限制了思路. 在网上搜了很多合并单元格的都是简单的数据合并,也就是td合并, 不是我们的需求,就不贴了. 哎,废话不多说了,看代码吧: 代码示例 使用iviewui的table组件: 最初,直接使用项目中的iv

QTableView中修改某个单元格或者行或者列内容颜色

QTableView的单元格内容实现还是继承了TableViewModel类的data(const QModelIndex &index, int role) const函数,那个设置颜色的问题也就在这个里面实现了. 1.设置某个单元格颜色 1 QVariant TableViewModel::data(const QModelIndex &index, int role) const 2 { 3 if (!index.isValid()) 4 return QVariant(); 5 i

poi导出excel合并单元格(包括列合并、行合并)

1 工程所需jar包如下:commons-codec-1.5.jarcommons-logging-1.1.jarlog4j-1.2.13.jarjunit-3.8.1.jarpoi-3.9-20121203.jar 2 Code: /** * 导出设备信息Excel * @param form 和 HTTP 请求相关的表格对象 * @param resources 信息资源对象 * @param locale 本地化对象 * @param session HTTP 会话对象 * @param

DataGridView合并单元格(一列或一行)之一

#region"合并单元格的测试(一列或一行)" // int?是搜索一种类型(可空类型),普通的int不能为null,而用int?,其值可以为null //private int? nextrow = null; //private int? nextcol = null; //在CellPainting方法后调用 private void dataGridView1_CellFormatting(object sender, System.Windows.Forms.DataGri

【记录】解析具有合并单元格的Excel

最近公司让做各种数据表格的导入导出,就涉及到电子表格的解析,做了这么多天总结一下心得. 工具:NOPI 语言:C# 目的:因为涉及到导入到数据库,具有合并单元格的多行必然要拆分,而NPOI自动解析的时候拆分单元格除第一个单元格外其余值都是空,对于列头有合并项目的,数据库设计一般才有合并单元格下面的最小列单元作为数据库字段.于是希望达到这样一个效果.于是有了一个思路就是把读入的Excel复制到新建的Excel,然后再去读新的Excel.总体思路就是把合并单元格所包含的所有最小单元格的值都设置成合并

NPOI操作EXCEL(五)——含合并单元格复杂表头的EXCEL解析

我们在第三篇文章中谈到了那些非常反人类的excel模板,博主为了养家糊口,也玩命做出了相应的解析方法... 我们先来看看第一类复杂表头: ...... 博主称这类excel模板为略复杂表头模板(蓝色部分为表头部分,蓝色前面几行是博主项目的基础样式,称为元数据),这类excel的表头多为2-3行,甚至于5/6行 ,具有合并层级关系,看似复杂,但只需要在我们以前的基础上稍微做一下重构就可以完美实现解析. 我们以各地区户籍人口城乡构成表头为例: 其实,只要我们能准确解析这类表头所表达的意思,就能复用以

apache poi 合并单元格 设置边框

HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet(); //创建一个样式 HSSFCellStyle styleBorderThin= wb.createCellStyle(); setBorder.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框 setBorder.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左

让我头疼一下午的Excel合并单元格

Excel导出常见问题 excel导出其实不算什么难事 在网上copy下模板代码,填充自己的业务数据,提供一个http接口基本就可以得到你要导出的数据了. 但是,凡事都有例外,截止今天,excel导出我遇到的主要是两大类问题 1.大数据量的excel数据,比如几十万条甚至更多的数据导出 2.因为excel中内容的问题,导致导出后的excel不能直接打开,报错"由于一些内容不可取,Excel无法打开xxx.xlsx.是否要打开并修复此工作簿?" 针对第一种大数据量问题,我遇到的主要问题是