首页 > 编程语言 >使用C#将几个Excel文件合并去重分类

使用C#将几个Excel文件合并去重分类

时间:2023-11-15 10:48:04浏览次数:34  
标签:Excel C# list Cells 合并 Value worksheet new

需要将几个Excel表格里面的数据去重,然后将每个站点的数据另存为一张Sheet上。

几个表格如下所示:

 

 

实现效果如下所示:

 

具体实现

需要使用EPPlus操作Excel

安装EPPlus如下所示:

 

为了更好的演示与说明,把步骤进行了拆分,先导入Excel数据,再去重,再进行数据分类,最后再导出为Excel数据,设计了一个窗体,如下所示:

 

导入Excel数据

首先定义一个类,用来保存相关数据,类的设计如下:

 public class WaterData
 {
      public int Id { get; set; }
      public string? Name { get; set; }
      public string? WaterLevel { get; set; }
      public string? WaterChange { get; set; }
      public string? Source { get; set; }
     
 }

点击导入Excel数据按钮的代码如下:

OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Excel Files (*.xlsx; *.xls;*.csv)|*.xlsx; *.xls;*.csv";
openFileDialog.FilterIndex = 1;
openFileDialog.Multiselect = false;
​
   if (openFileDialog.ShowDialog() == DialogResult.OK)
      {
          filePath = openFileDialog.FileName;       
          ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
          using (ExcelPackage package = new ExcelPackage(filePath))
           {
​
               ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
​
                //获取表格的列数和行数
                int rowCount = worksheet.Dimension.Rows;
                int colCount = worksheet.Dimension.Columns;
​
                for (int i = 0; i < rowCount - 1; i++)
                {
                   //创建一个realData类保存数据
                   var data = new WaterData();
             data.Id = n;
             data.Name = (string)worksheet.Cells[i + 2, 3].Value;
             data.WaterLevel = Convert.ToString(worksheet.Cells[i + 2, 4].Value);
             data.WaterChange = Convert.ToString(worksheet.Cells[i + 2, 5].Value);
             data.Source = (string)worksheet.Cells[i + 2, 2].Value;
             waterList.Add(data);
                     n++;
                    }         
             package.Save();
​
                }
            }
            else
            {
​
                MessageBox.Show("您本次没有选择任何文件!!!");
            }
        }

上面的n是static int,初始值为0。

导入Excel数据的效果如下所示:

数据去重

执行数据去重,依据的是C#LINQ中的DistinctBy方法,本例中不使用id是因为每条数据id都不一样,即使是重复的数据但是id也不一样,本例依据的中Name属性和Soure属性,只要这两个数据一样,就认为是重复数据。

点击数据去重按钮的代码如下:

private void button2_Click(object sender, EventArgs e)
{    
    distinctList = waterList.DistinctBy(x => new { x.Name, x.Source }).ToList(); 
}

只需要一行代码:

distinctList = waterList.DistinctBy(x => new { x.Name, x.Source }).ToList();

执行去重的效果如下所示:

执行数据分类

本例中要求将同一个站点的数据放在同一张Sheet上,那么首先需要知道到底有多少个不同的站名,代码如下:

 var Names = distinctList.Select(x => x.Name).Distinct().ToList(); 

实现效果如下:

由于这些数据是由图片文字识别而来的,因此可能识别有误,如果一个站名的数据不足50条,就不需要,代码如下:

 for (int i = 0; i < Names.Count; i++)
  {
     var nameList = distinctList.Where(x => x.Name == Names[i]).ToList();
     if (nameList.Count > 50) 
         {
               list.Add(nameList);
          }            
   }  

实现数据分类也只需要一行代码:

var nameList = distinctList.Where(x => x.Name == Names[i]).ToList();

实现效果如下所示:

导出为Excel文件

本例中导出为Excel文件的思路是先让用户选定一个文件夹,然后就将导出的Excel文件保存在这个文件夹下面,导出为Excel文件的代码如下:

 private void button4_Click(object sender, EventArgs e)
        {
            // 创建一个FolderBrowserDialog对象
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
​
            // 设置对话框的标题
            folderBrowserDialog.Description = "选择保存各站点数据的文件夹";
​
            // 设置默认的根文件夹,如果需要的话
            // folderBrowserDialog.RootFolder = Environment.SpecialFolder.MyComputer;
​
            // 显示文件夹选择对话框
            DialogResult result = folderBrowserDialog.ShowDialog();
​
            if (result == DialogResult.OK)
            {
                // 用户选择了一个文件夹
                selectedFolderPath = folderBrowserDialog.SelectedPath;
                richTextBox1.Text += $"选择的Excel保存文件夹为:{selectedFolderPath}\r\n";
                richTextBox1.Text += "正在执行导出为Excel文件...";
                using (ExcelPackage excelPackage = new ExcelPackage())
                {                 
                    for(int i =0; i < list.Count; i++) 
                    {
                        ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets.Add(list[i][0].Name);
                        for (int j = 0; j < list[i].Count; j++)
                        {
                            worksheet.Cells[j + 1, 1].Value = list[i][j].Id;
                            worksheet.Cells[j + 1, 2].Value = list[i][j].Name;
                            worksheet.Cells[j + 1, 3].Value = list[i][j].WaterLevel;
                            worksheet.Cells[j + 1, 4].Value = list[i][j].WaterChange;
                            worksheet.Cells[j + 1, 5].Value = list[i][j].Source;
                        }
                    }
​
                    // 保存 Excel 文件
                    FileInfo excelFile = new FileInfo($"{selectedFolderPath}\\各站点数据.xlsx");
                    excelPackage.SaveAs(excelFile);
                    richTextBox1.Text += "导出为Excel文件完成\r\n";
                }
            }
        }

实现效果如下所示:

 

最后

操作Excel大家一般使用VBA、Python比较多,本文通过一个实例演示了如何通过C#来简化我们的办公(处理Excel数据)。

本实例全部源代码如下:

using OfficeOpenXml;
using System.Collections;
using System.Collections.Generic;
​
namespace Excel数据处理
{
    public partial class Form1 : Form
    {
        string filePath;
        string selectedFolderPath;
        static int n = 0;
        List<WaterData> waterList = new List<WaterData>();
        List<WaterData> distinctList = new List<WaterData>();
        List<List<WaterData>> list = new List<List<WaterData>>();
        public class WaterData
        {
            public int Id { get; set; }
            public string? Name { get; set; }
            public string? WaterLevel { get; set; }
            public string? WaterChange { get; set; }
            public string? Source { get; set; }
​
        }
​
​
        public Form1()
        {
            InitializeComponent();
        }
​
        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Excel Files (*.xlsx; *.xls;*.csv)|*.xlsx; *.xls;*.csv";
            openFileDialog.FilterIndex = 1;
            openFileDialog.Multiselect = false;
​
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                filePath = openFileDialog.FileName;
                richTextBox1.Text += $"您选中的文件路径为:{filePath}\r\n";
                richTextBox1.Text += $"正在导入Excel数据...\r\n";
                ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
                using (ExcelPackage package = new ExcelPackage(filePath))
                {
​
                    ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
​
                    //获取表格的列数和行数
                    int rowCount = worksheet.Dimension.Rows;
                    int colCount = worksheet.Dimension.Columns;
​
                    for (int i = 0; i < rowCount - 1; i++)
                    {
                        //创建一个realData类保存数据
                        var data = new WaterData();
                        data.Id = n;
                        data.Name = (string)worksheet.Cells[i + 2, 3].Value;
                        data.WaterLevel = Convert.ToString(worksheet.Cells[i + 2, 4].Value);
                        data.WaterChange = Convert.ToString(worksheet.Cells[i + 2, 5].Value);
                        data.Source = (string)worksheet.Cells[i + 2, 2].Value;
                        waterList.Add(data);
                        n++;
                    }
                    richTextBox1.Text += $"导入Excel数据成功,数据量为:{rowCount - 1}\r\n";
                    package.Save();
​
                }
            }
            else
            {
​
                MessageBox.Show("您本次没有选择任何文件!!!");
            }
        }
​
        private void button2_Click(object sender, EventArgs e)
        {
            richTextBox1.Text += "正在执行数据去重...\r\n";
            distinctList = waterList.DistinctBy(x => new { x.Name, x.Source }).ToList();
            richTextBox1.Text += $"数据去重已完成,去重后数据量为:{distinctList.Count}\r\n";
        }
​
        private void button3_Click(object sender, EventArgs e)
        {
            richTextBox1.Text += "正在执行数据分类...\r\n";
            var Names = distinctList.Select(x => x.Name).Distinct().ToList();          
            for (int i = 0; i < Names.Count; i++)
            {
                var nameList = distinctList.Where(x => x.Name == Names[i]).ToList();
                if (nameList.Count > 50) 
                {
                    list.Add(nameList);
                }            
            }
            richTextBox1.Text += $"执行数据分类完成,类数为:{list.Count}\r\n";
        }
​
        private void button4_Click(object sender, EventArgs e)
        {
            // 创建一个FolderBrowserDialog对象
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
​
            // 设置对话框的标题
            folderBrowserDialog.Description = "选择保存各站点数据的文件夹";
​
            // 设置默认的根文件夹,如果需要的话
            // folderBrowserDialog.RootFolder = Environment.SpecialFolder.MyComputer;
​
            // 显示文件夹选择对话框
            DialogResult result = folderBrowserDialog.ShowDialog();
​
            if (result == DialogResult.OK)
            {
                // 用户选择了一个文件夹
                selectedFolderPath = folderBrowserDialog.SelectedPath;
                richTextBox1.Text += $"选择的Excel保存文件夹为:{selectedFolderPath}\r\n";
                richTextBox1.Text += "正在执行导出为Excel文件...";
                using (ExcelPackage excelPackage = new ExcelPackage())
                {                 
                    for(int i =0; i < list.Count; i++) 
                    {
                        ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets.Add(list[i][0].Name);
                        for (int j = 0; j < list[i].Count; j++)
                        {
                            worksheet.Cells[j + 1, 1].Value = list[i][j].Id;
                            worksheet.Cells[j + 1, 2].Value = list[i][j].Name;
                            worksheet.Cells[j + 1, 3].Value = list[i][j].WaterLevel;
                            worksheet.Cells[j + 1, 4].Value = list[i][j].WaterChange;
                            worksheet.Cells[j + 1, 5].Value = list[i][j].Source;
                        }
                    }
​
                    // 保存 Excel 文件
                    FileInfo excelFile = new FileInfo($"{selectedFolderPath}\\各站点数据.xlsx");
                    excelPackage.SaveAs(excelFile);
                    richTextBox1.Text += "导出为Excel文件完成\r\n";
                }
            }
        }
    }
}

如果你也对C#感兴趣,欢迎关注微信公众号DotNet学习交流~

标签:Excel,C#,list,Cells,合并,Value,worksheet,new
From: https://www.cnblogs.com/mingupupu/p/17833301.html

相关文章

  • eventSource(SSE)的实践
     1.概述目前JS实时通信方式主要由:websocket、socket.io、eventSource(SSE)这三种方式。对于这三种方式,不同客户端场景有着其各自的优势。EventSource是单向通信,而websocket是双向通信。在新闻推送、股票行情这种只需要服务器发送消息给客户端场景,使用SSE更加合适,另外SSE是使用H......
  • 用bash脚本快速生成/管理openwrt .config配置文件
    Openwrt自带的图形化配置工具非常方便,但如果自己编译的时候经常要改设置,需要选中或者取消的package散落在图形配置的各个角落,那无疑是非常痛苦的一件事,下面用bash脚本来优化这一流程。下面以生成x86固件为例首先备份你已有的.config配置文件,然后makemenuconfig,在架构中选中x86-......
  • C# 开发浏览器拓展工具
    1、安装Blazor.BrowserExtension.Template模板dotnetnew--installBlazor.BrowserExtension.Template2、新建项目dotnetnewbrowserext--name 你的项目名称   3、修改代码 4、运行程序 5、测试页面\index.html 6、edge开启开发者模式 输入chrome:......
  • C++ 程序数据传输到动态库后,出现乱码
    程序结构体和动态库结构体如下structVehInfo{ intID; intlaneId; VEHSTATEvehstate; intleftX; intrightX; intleftXSignal;//单车道的左位置 intrightXSignal;//单车道的右位置 intvehLen; intvehWidth; intvehHeight; /*****************************......
  • oracle 查看SQL执行计划
    参考:https://blog.csdn.net/m0_71406734/article/details/130745657执行计划的目的了解SQL语句的执行方式,帮助开发人员和DBA分析SQL语句的性能瓶颈。查看SQL语句的执行效率,帮助开发人员和DBA优化SQL语句的性能。了解数据库的物理结构,如索引、表之间的连接方式等。帮助开发人......
  • crontab任务以user用户执行hive -f命令不生效解决记录
    现象:创建了一个shell脚本任务,使用crontab进行任务调度,其中hive执行为: hive-f/opt/test.sql>/opt/test.log2>&1任务调度起来后一直报错提示: /usr/bin/hive:行3:/parcels/sbin/configure.sh:没有那个文件或目录 解决:1.使用hive绝对路径:首先保证user用户有启动hive的......
  • cq9玩家异想天开:苹果官网购iPhone 15竟然变身电子游戏的安卓山寨机!
    网购惊现苹果官网iPhone假货事件!英国网友Ed在Reddit上分享了他的离奇经历,从苹果官网购买的iPhone15ProMax竟然变成了一部Android山寨手机。外包装与正品无异,然而打开后发现手机下巴异常宽,原来安装的是伪装的Android系统。Ed强调他是从苹果官网购买,并提供了订单和出货确认信,使用D......
  • 无涯教程-Dart - truncate函数
    丢弃任何小数位后返回整数。truncate-语法Number.truncate()truncate-返回值返回不带小数点的int。truncate-示例voidmain(){doublen1=2.123;varvalue=n1.truncate();print("Thetruncatedvalueof2.123=${value}");}它将产生以下输出-......
  • Vue-cli 用自定义的组件有遇到过哪些问题?
    在components目录新建你的组件文件(indexPage.vue),script一定要exportdefault{}在需要用的页面(组件)中导入:importindexPagefrom'@/components/indexPage.vue'注入到vue的子组件的components属性上面,components:在template视图view中使用,例如命名为inde......
  • [ARC123E] Training
    多测,求值\[\sum_{i=1}^{n}\Big[a+\lfloor\frac{i}{b}\rfloor=c+\lfloor\frac{i}{d}\rfloor\Big]\]\(1\leT\le2\times10^5\),\(1\len\le10^9\),\(1\lea,b,c,d\le10^6\)。没见过,还得是广附哥。令\(b\led\),设\(f(x)=a+\dfrac{x}{b}\),\(g(x)=c+......