如何使用C#从文件夹内多个Excel文件提取数据并导出为新文件
C# 多Excel文件数据提取合并导出实现方案
前置依赖
推荐使用EPPlus库实现,无需本地安装Microsoft Office,操作便捷:
- NuGet安装命令:
Install-Package EPPlus - .NET CLI安装命令:
dotnet add package EPPlus
注意:EPPlus 5及以上版本非商业使用免费,商业场景使用需购买官方授权,也可替换为NPOI、MiniExcel等无授权限制的开源库。
核心实现代码
using OfficeOpenXml; using System.IO; class ExcelMergeTool { static void Main(string[] args) { // 配置EPPlus许可(非商业场景使用) ExcelPackage.LicenseContext = LicenseContext.NonCommercial; // 请自行修改以下路径为你的实际路径 string sourceFolderPath = @"C:\你的源Excel文件夹路径"; string targetFilePath = @"C:\导出结果\合并结果.xlsx"; // 创建目标Excel文件 using (var targetPackage = new ExcelPackage(new FileInfo(targetFilePath))) { // 提前创建所需的所有工作表 var sheetAtten1 = targetPackage.Workbook.Worksheets.Add("Atten1"); var sheetIdrive1 = targetPackage.Workbook.Worksheets.Add("Idrive1"); var sheetIdrive2 = targetPackage.Workbook.Worksheets.Add("Idrive2"); var sheetGates1 = targetPackage.Workbook.Worksheets.Add("Gates1"); var sheetTemps = targetPackage.Workbook.Worksheets.Add("Temps"); // 记录每个工作表当前写入的行号,默认从第1行开始写表头,可根据需求调整 int rowAtten1 = 1, rowIdrive1 = 1, rowIdrive2 = 1, rowGates1 = 1, rowTemps = 1; // 遍历源文件夹下所有Excel文件 var excelFiles = Directory.GetFiles(sourceFolderPath, "*.xlsx", SearchOption.TopDirectoryOnly); foreach (var file in excelFiles) { using (var sourcePackage = new ExcelPackage(new FileInfo(file))) { // 遍历源文件的所有工作表(如果你的数据都在第一个工作表,可直接取Worksheets[0]) foreach (var sourceSheet in sourcePackage.Workbook.Worksheets) { int sourceRowCount = sourceSheet.Dimension?.End.Row ?? 0; if (sourceRowCount == 0) continue; // 提取Atten1列数据,假设列名在第1行,可根据实际结构调整列索引 for (int row = 1; row <= sourceRowCount; row++) { var cellVal = sourceSheet.Cells[row, GetColumnIndexByName(sourceSheet, "Atten1")].Text; if (!string.IsNullOrEmpty(cellVal)) { sheetAtten1.Cells[rowAtten1++, 1].Value = cellVal; } } // 提取Idrive1列数据 for (int row = 1; row <= sourceRowCount; row++) { var cellVal = sourceSheet.Cells[row, GetColumnIndexByName(sourceSheet, "Idrive1")].Text; if (!string.IsNullOrEmpty(cellVal)) { sheetIdrive1.Cells[rowIdrive1++, 1].Value = cellVal; } } // 提取Idrive2列数据 for (int row = 1; row <= sourceRowCount; row++) { var cellVal = sourceSheet.Cells[row, GetColumnIndexByName(sourceSheet, "Idrive2")].Text; if (!string.IsNullOrEmpty(cellVal)) { sheetIdrive2.Cells[rowIdrive2++, 1].Value = cellVal; } } // 提取Gates1列数据 for (int row = 1; row <= sourceRowCount; row++) { var cellVal = sourceSheet.Cells[row, GetColumnIndexByName(sourceSheet, "Gates1")].Text; if (!string.IsNullOrEmpty(cellVal)) { sheetGates1.Cells[rowGates1++, 1].Value = cellVal; } } // 提取所有Temps相关数据,整行写入Temps工作表 int tempColCount = sourceSheet.Dimension.End.Column; for (int row = 1; row <= sourceRowCount; row++) { // 可以判断当前行是否是Temps相关数据,或者直接全量写入,根据你的需求调整 for (int col = 1; col <= tempColCount; col++) { sheetTemps.Cells[rowTemps, col].Value = sourceSheet.Cells[row, col].Text; } rowTemps++; } } } } // 保存目标文件 targetPackage.Save(); } } // 根据列名获取列索引,适配表头位置为第1行的场景,可根据实际调整 private static int GetColumnIndexByName(ExcelWorksheet sheet, string columnName) { int colCount = sheet.Dimension?.End.Column ?? 0; for (int col = 1; col <= colCount; col++) { if (sheet.Cells[1, col].Text.Trim().Equals(columnName, StringComparison.OrdinalIgnoreCase)) { return col; } } return -1; } }
自定义调整说明
- 代码默认适配表头在第1行的Excel结构,你可以根据实际的源文件表头位置、列名调整匹配逻辑
- 如果需要保留原数据的数值格式(比如数字、日期格式),可以直接赋值
Value而非Text,同时设置对应单元格的格式属性 - 如需处理
.xls格式的旧版Excel文件,可以替换EPPlus为NPOI库,逻辑思路一致
内容的提问来源于stack exchange,提问作者Benjamin Rios
相关产品推荐
相关产品推荐

