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

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

时间:2023-11-29 19:00:11浏览次数:31  
标签: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(); 
}

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

 

执行数据分类

本例中要求将同一个站点的数据放在同一张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);
     }            
   }

实现效果如下所示:

 

导出为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";
                }
            }
        }
    }
}

 

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

相关文章

  • Logcat
    使用Logcat写入和查看日志 | Android开发者 | AndroidDevelopershttps://developer.android.google.cn/studio/debug/am-logcat?hl=zh-cn使用Logcat写入和查看日志AndroidStudio中的Logcat窗口会显示系统消息,例如在进行垃圾回收时显示的消息,以及使用 Log ......
  • 全网最详细!Centos7.X 搭建Grafana+Jmeter+Influxdb 性能实时监控平台 (上)
    来源:https://developer.aliyun.com/article/907041本文涉及的产品可观测可视化Grafana版,10个用户账号1个月 立即试用 简介: 全网最详细!Centos7.X搭建Grafana+Jmeter+Influxdb性能实时监控平台(上)背景日常工作中,经常会用到Jmeter......
  • c++跨文件修改成员变量
    如果在一个文件中有一个成员变量,需要在另外一个文件中修改这个成员变量。把这个成员变量加一个static变成静态成员变量即可。如下所示:在A.cpp中有student类classstudent{public:student();public://声明静态成员函数staticintgetTotal();staticfloat......
  • LogFacade---SLF4J
    概述SimpleLoggingFacadeforJava(SLF4J);用作各种日志框架(eg:java.util.logging,logback,log4j)的简单外观或抽象,允许最终用户在部署时插入所需的日志记录框架; 不提供完整的日志记录解决方案;使用SLF4J无法执行配置appender或设置日志记录级别等操作。因此,在某个时间点,任何非......
  • DCR-2855路由器升级
    #命令介绍:利用copy命令使用copy命令可以从TFTP服务器读取文件到路由器flash闪存,也可以将路由器flash闪存中的某个文件写到TFTP服务器。或者从CF卡读取文件到路由器flash闪存或TFTP服务器,也可将TFTP服务器或路由器flash闪存中的某个文件写到CF卡。或者从......
  • 云边协同的 RTC 如何助力即构全球实时互动业务实践
    由51CTO主办的“WOT全球技术创新大会2023·深圳站”于11月24日-25日召开,即构科技后台技术总监肖潇以“边缘容器在全球音视频场景的探索与实践”为主题进行分享。边缘计算作为中心云计算的补充,通过边缘容器架构和云边协同,为音视频、云游戏、元宇宙等场景带来了更好的用......
  • 【influxDB】CentOS 7.x InfluxDB 1.8.0的安装使用
    一、安装wgethttps://dl.influxdata.com/influxdb/releases/influxdb-1.8.0.x86_64.rpmyum-ylocalinstallinfluxdb-1.8.0.x86_64.rpm image.pngsystemctlstartinfluxdbsystemctlenableinfluxdbsystemctlstatusinfluxdbss-tan|grep8086......
  • [LettCode-中等] 字母异位词分组
    这是一道中等难度题,首先我们来了解一下,什么是字母异位词 =》由重新排列源单词的所有字母得到一个新单词字母异位词=》它是这个意思,比如说一个字符串由3个字符abc组成,就是"abc",现在我把组成这个字符串的字母顺序随意调换,比如变成"bac","bca","cab"等,这几个词就是字母异位......
  • 浏览器插件 Obsidian web 与 Obsidian 插件 local rest api 结合配置过程记录
    1.安装浏览器插件能到这里的肯定是已经有Obsidian了.首先要安装chrome浏览器插件Obsidianweb如图2.安装Obsidian上的插件插件名为localrestapi,如图3.设置浏览器插件配置对应的Obsidianweb中设置上localrestapi的信息,需要简单理解一下,就是......
  • 九、安装Docker Compose 编排工具
    根据前面所学的知识可知,想要使用Docker部署应用,就要先在应用中编写Dockerfile文件来构建镜像。同样,在微服务项目中,我们也需要为每一个服务编写Dockerfile文件来构建镜像。构建完成后,就可以根据每一个镜像使用dockerrun或者dockerservicecreate命令创建并启动容器,这样我们就可......