(二)对导入的Excel某列进行合并、求和,删除重复行

第一次真正意义上做小项目,根据对方所提需求,慢慢的学习并实践。
在之前我们是通过ExcelDataReader插件将Excel的内容导入datagridview控件,那今天是将导入的数据从datagridview中导出为Excel。
在导出时需要进行一些特殊的处理。

(一)界面设计

我的界面不是那么美观,哈哈哈,我也想好看,搞不出来,呜呜。
在这里插入图片描述

(二)代码块

导入的过程上一篇内容有了,这块主要是导出过程的代码啦。

(1)导出数据部分

  private void ExportToExcel(DataGridView dataGridView1)

        {
            if (txtFileName.Text.Equals(""))
            {
                MessageBox.Show("未打开文件,请打开文件!");
                return;
            }
            if (dataGridView1.Rows.Count == 0)
            {
                MessageBox.Show("请选择表格");
                return;
            }
            if (addColumns.Text == "" || joinColumns.Text == "" || duplicateColumn.Text == "")
            {
                MessageBox.Show("请输入要操作的列!");
                return;

            }
            //声明一个字符串来接收文本的路径
            string fileName = "";
            string saveFileName = "";
            SaveFileDialog saveDialog = new SaveFileDialog();
            //扩展名
            saveDialog.DefaultExt = "xlsx";
            saveDialog.Filter = "Excel文件| *.xlsx;*.xls";
            //打开文件夹保存位置
            saveDialog.ShowDialog();
            saveFileName = saveDialog.FileName;
          
            if (saveFileName.IndexOf(":") < 0) return;  //被点了取消

            //创建Excel
            Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();

            //判断创建Excel有没有成功
            if (xlApp == null)

            {
                MessageBox.Show("无法创建Excel对象,您可能未安装Excel");

                return;

            }

            //工作簿对象
            Microsoft.Office.Interop.Excel.Workbooks workbooks = xlApp.Workbooks;
            //System.Reflection.Missing miss = System.Reflection.Missing.Value;

            //创建工作簿(Workbook:即Excel文件主体本身)
            Microsoft.Office.Interop.Excel.Workbook workbook = workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);

            //创建工作表(即Excel里的子表sheet)1表示在子表sheet1里进行数据导出
            Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[1]; //取得sheet1

            //将数据导入到工作表的单元格
            //写入标题行
            for (int a = 0; a < dataGridView1.Columns.Count; a++)
            {
                if (this.dgvData.Columns[a].Visible == true)
                {
                    //列标题单元格的标题文本  //excel单元格第一个从索引1开始,第一行第a+1列,因为a从0开始取
                    worksheet.Cells[1, a + 1] = dataGridView1.Columns[a].HeaderText;
                }
            }
            


            ///把DataGridView当前页的数据保存在Excel中 ///
            //求和列值
        
            int addColumn = 1;
            addColumn = Convert.ToInt32(addColumns.Text);
            //addColumn = addColumn + 1;
            //拼接列
            int joinColumn = 1;
            joinColumn = Convert.ToInt32(joinColumns.Text);
            //joinColumn = joinColumn + 1;
            //重复列
            int duplicateIs = 1;
            duplicateIs = Convert.ToInt32(duplicateColumn.Text);

            bool isDuplicate;
            int i = 0;
            while (i < dataGridView1.Rows.Count)
            {
               
                isDuplicate = false;//是否重复  
                List<int> list = new List<int>();
                //行之间比较
                for (int nbRowCompare = i; nbRowCompare < dataGridView1.Rows.Count; nbRowCompare++)
                {
                    if (dataGridView1[duplicateIs - 1, nbRowCompare].Value != null)
                    {
                        //判断是否重复
                        if (dataGridView1[duplicateIs - 1, nbRowCompare].Value.ToString().Equals(dataGridView1[duplicateIs - 1, i].Value.ToString()))
                        {
                            //重复的放在这里面  (把对象放入集合)
                            list.Add(nbRowCompare);
                            isDuplicate = true;
                        }
                    }
                }                
                //Console.WriteLine(list);
                //如果重复,将第二列的内容拼接   拼接第几列
                if (isDuplicate)
                {                   
                    for (int a = 1; a < list.Count; a++)
                    {
                        //拼接      如果为空则无,不为空则连接
                        if (dataGridView1[joinColumn - 1, list[a]].Value == null || (dataGridView1[joinColumn - 1, list[a]].Value.ToString()).Equals(""))
                        {
                        }
                        else
                        {
                            拼接
                            dataGridView1[joinColumn - 1, list[0]].Value += "," + (string)(dataGridView1[joinColumn - 1, list[a]].Value);
                            //求和列
                            dataGridView1[addColumn - 1, list[0]].Value = Convert.ToInt32(dataGridView1[addColumn - 1, list[0]].Value.ToString()) + Convert.ToInt32(dataGridView1[addColumn - 1, list[a]].Value.ToString());
                        }
                    }
                    //删除重复行
                    for (int a = list.Count - 1; a > 0; a--)
                    {
                        dataGridView1.Rows.RemoveAt(list[a]);
                    }
                }

                for (int j = 0; j < dataGridView1.Columns.Count; j++)
                {

                    if (dataGridView1[j, i].Value != null)
                    {
                    //Fun函数调用
                      dataGridView1[joinColumn - 1, i].Value = Fun(dataGridView1[joinColumn - 1, i].Value.ToString());
                        worksheet.Cells[i + 2, j + 1] = dataGridView1[j, i].Value.ToString();
                    }
                }

                i++;
                ProgressBar1.Maximum = dataGridView1.Rows.Count;
                ProgressBar1.Value = i;
                Application.DoEvents();
            }
                //该对象代表整个范围列(或列),其中包含指定的范围。  //列宽自适应
                //worksheet.Columns.EntireColumn.AutoFit();
                //提示框
                MessageBox.Show(fileName + "保存成功");
                if (saveFileName != "")
                {
                    try
                    {
                        workbook.Saved = true;
                        //保存工作簿的副本文件但不修改打开工作簿在内存中。
                        workbook.SaveCopyAs(saveFileName);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("导出文件可能正在被打断!" + ex.Message);

                    }
                }
                //释放可能还没有释放的进程
                xlApp.Quit();
                GC.Collect();
        }

(2)拆分字符函数

 public string Fun(string input)
        {
            List<string> resultStr = new List<string>();
            //例如:   C164 - C166,C360 - C362
            string[] vs1 = input.Split(','); //C164-C166  C360-C362
            foreach (string s in vs1)
            {
                if (s.Contains('-'))
                {
                    //C164 - C166
                    string[] vs2 = s.Split('-');
                    //C164  C166
                    string start = Regex.Replace(vs2[0], "[a-z]", "", RegexOptions.IgnoreCase);//C164
                    string end = Regex.Replace(vs2[1], "[a-z]", "", RegexOptions.IgnoreCase);//C166
                    string code = vs2[0].Replace(start, "");//C = ""
                    int start1 = Convert.ToInt32(start);//164
                    int end1 = Convert.ToInt32(end);//166
                    for (int a = start1; a <= end1; a++)
                    {
                        //164
                        string rs = code + a;//C164
                        resultStr.Add(rs);
                    }
                }
                else
                {
                    resultStr.Add(s);
                }

            }
            //resultStr C164 C165 C166 C360 C361 C362
            return string.Join(",", resultStr);
        }

(3)结果展示

在这里插入图片描述
我这个板块具体得功能是选择相应料号列、点位列、点位数量列后,完成将料号列重复行删除,在删除前,将它的点位列拼接上,同时计算点位用量列的和。

(4)例子

导出前:
在这里插入图片描述
导出后:
在这里插入图片描述
在某些内容我可能解释的不是很清楚,大家可以看代码里的注释。有什么问题,可私或评论区见。希望对有需要的伙伴有所帮助。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值