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

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

需要将几个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)

实现效果如下所示:

导出为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 如何利用Pivot Table将日期时间直接分类为月汇总
Excel 如何利用Pivot Table将日期时间直接分类为月汇总
Excel 如何利用Pivot Table将日期时间直接分类为月汇总
|
2月前
|
人工智能 算法 安全
使用CodeBuddy实现批量转换PPT、Excel、Word为PDF文件工具
通过 CodeBuddy 实现本地批量转换工具,让复杂的文档处理需求转化为 “需求描述→代码生成→一键运行” 的极简流程,真正实现 “技术为效率服务” 的目标。感兴趣的快来体验下把
104 10
|
2月前
|
存储 监控 算法
基于 C# 的局域网计算机监控系统文件变更实时监测算法设计与实现研究
本文介绍了一种基于C#语言的局域网文件变更监控算法,通过事件驱动与批处理机制结合,实现高效、低负载的文件系统实时监控。核心内容涵盖监控机制选择(如事件触发机制)、数据结构设计(如监控文件列表、事件队列)及批处理优化策略。文章详细解析了C#实现的核心代码,并提出性能优化与可靠性保障措施,包括批量处理、事件过滤和异步处理等技术。最后,探讨了该算法在企业数据安全监控、文件同步备份等场景的应用潜力,以及未来向智能化扩展的方向,如文件内容分析、智能告警机制和分布式监控架构。
62 3
|
7月前
|
人工智能 自然语言处理 Java
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
FastExcel 是一款基于 Java 的高性能 Excel 处理工具,专注于优化大规模数据处理,提供简洁易用的 API 和流式操作能力,支持从 EasyExcel 无缝迁移。
1501 65
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
|
5月前
|
文字识别 Serverless 开发工具
【全自动改PDF名】批量OCR识别提取PDF自定义指定区域内容保存到 Excel 以及根据PDF文件内容的标题来批量重命名
学校和教育机构常需处理成绩单、报名表等PDF文件。通过OCR技术,可自动提取学生信息并录入Excel,便于统计分析和存档管理。本文介绍使用阿里云服务实现批量OCR识别、内容提取、重命名及导出表格的完整步骤,包括开通相关服务、编写代码、部署函数计算和设置自动化触发器等。提供Python示例代码和详细操作指南,帮助用户高效处理PDF文件。 链接: - 百度网盘:[链接](https://pan.baidu.com/s/1mWsg7mDZq2pZ8xdKzdn5Hg?pwd=8866) - 腾讯网盘:[链接](https://share.weiyun.com/a77jklXK)
505 5
|
5月前
|
文字识别 BI
【图片型PDF】批量识别扫描件PDF指定区域局部位置内容,将识别内容导出Excel表格或批量改名文件,基于阿里云OCR对图片型PDF识别改名案例实现
在医疗和政务等领域,图片型PDF文件(如病历、报告、公文扫描件)的处理需求广泛。通过OCR技术识别这些文件中的文字信息,提取关键内容并保存为表格,极大提高了信息管理和利用效率。本文介绍一款工具——咕嘎批量OCR系统,帮助用户快速处理图片型PDF文件,支持区域识别、内容提取、导出表格及批量改名等功能。下载工具后,按步骤选择处理模式、进行区域采样、批量处理文件,几分钟内即可高效完成数百个文件的处理。
561 8
|
7月前
|
开发框架 .NET Java
C#集合数据去重的5种方式及其性能对比测试分析
C#集合数据去重的5种方式及其性能对比测试分析
89 11
|
7月前
|
Python
按条件将Excel文件拆分到不同的工作表
使用Python的pandas库,可以轻松将Excel文件按条件拆分到不同的工作表中。本文通过一个示例代码展示了如何生成一个包含总成绩表和三个班级表的Excel文件。代码首先创建了一个包含学生姓名、班级和各科成绩的数据框,然后按班级分组,将每个班级的数据分别写入不同的工作表。最后,生成的Excel文件将包含四个工作表,分别为总成绩表和三个班级的成绩表。
115 6
按条件将Excel文件拆分到不同的工作表
|
7月前
|
C#
基于 C# 编写的 Visual Studio 文件编码显示与修改扩展插件
基于 C# 编写的 Visual Studio 文件编码显示与修改扩展插件
139 9
|
7月前
|
开发框架 .NET Java
C#集合数据去重的5种方式及其性能对比测试分析
C#集合数据去重的5种方式及其性能对比测试分析
115 10

热门文章

最新文章