namespace WinFormsApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void btnBrowseSource_Click(object sender, EventArgs e) { using (FolderBrowserDialog dialog = new FolderBrowserDialog()) { dialog.Description = "选择Excel文件夹"; if (dialog.ShowDialog() == DialogResult.OK) { txtSourcePath.Text = dialog.SelectedPath; txtOutputPath.Text = dialog.SelectedPath; // 默认输出到源文件夹 Log($"源文件夹: {dialog.SelectedPath}"); } } } private void btnBrowseOutput_Click(object sender, EventArgs e) { using (FolderBrowserDialog dialog = new FolderBrowserDialog()) { dialog.Description = "选择输出文件夹"; if (dialog.ShowDialog() == DialogResult.OK) { txtOutputPath.Text = dialog.SelectedPath; Log($"输出文件夹: {dialog.SelectedPath}"); } } } private void btnClear_Click(object sender, EventArgs e) { txtSourcePath.Clear(); txtOutputPath.Clear(); txtLog.Clear(); progressBar.Value = 0; } private void btnExit_Click(object sender, EventArgs e) { Application.Exit(); } private void btnMerge_Click(object sender, EventArgs e) { // 前置校验 if (string.IsNullOrEmpty(txtSourcePath.Text) || string.IsNullOrEmpty(txtOutputPath.Text)) { MessageBox.Show("请选择源文件夹和输出文件夹", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } try { MergeExcel(); } catch (Exception ex) { MessageBox.Show($"合并过程中发生错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); Log($"合并失败: {ex.Message}"); } } private void MergeExcel() { var sourceDir = txtSourcePath.Text; var outputDir = txtOutputPath.Text; var outputFile = Path.Combine(outputDir, "合并结果.xlsx"); if (!Directory.Exists(sourceDir)) { MessageBox.Show("源文件夹不存在", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 查找xlsx文件(排除合并结果本身) var xlsxFiles = Directory.GetFiles(sourceDir, "*.xlsx") .Where(f => !Path.GetFileName(f).Equals("合并结果.xlsx", StringComparison.OrdinalIgnoreCase)) .ToArray(); if (xlsxFiles.Length == 0) { MessageBox.Show("未找到待合并的Excel文件", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Log($"找到 {xlsxFiles.Length} 个文件,开始合并..."); progressBar.Maximum = xlsxFiles.Length; progressBar.Value = 0; // 设置EPPlus许可证上下文 OfficeOpenXml.ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial; var allData = new List(); var headers = new List(); try { // 处理每个文件 for (int idx = 0; idx < xlsxFiles.Length; idx++) { var file = xlsxFiles[idx]; var fileName = Path.GetFileName(file); Log($"处理: {fileName}"); try { using (var package = new OfficeOpenXml.ExcelPackage(new FileInfo(file))) { if (package.Workbook.Worksheets.Count == 0) { Log($"跳过空文件: {fileName}"); continue; } var worksheet = package.Workbook.Worksheets[0]; // 使用第一个工作表 var table = new System.Data.DataTable(); // 获取表头 if (headers.Count == 0) { var columnCount = worksheet.Dimension.End.Column; for (int col = 1; col <= columnCount; col++) { var header = worksheet.Cells[1, col].Text?.Trim() ?? $"Column{col}"; headers.Add(header); table.Columns.Add(header); } } else { // 创建相同结构的表 foreach (var header in headers) { table.Columns.Add(header); } } // 跳过表头行,从第二行开始读取数据 var rowCount = worksheet.Dimension.End.Row; for (int row = 2; row <= rowCount; row++) { var dataRow = table.NewRow(); var isEmpty = true; for (int col = 0; col < headers.Count; col++) { var cellValue = worksheet.Cells[row, col + 1].Text; dataRow[col] = cellValue; if (!string.IsNullOrWhiteSpace(cellValue)) { isEmpty = false; } } if (!isEmpty) { table.Rows.Add(dataRow); } } if (table.Rows.Count > 0) { allData.Add(table); Log($"成功读取 {fileName}: {table.Rows.Count} 行数据"); } else { Log($"跳过无数据文件: {fileName}"); } } } catch (Exception ex) { Log($"处理失败: {fileName} - {ex.Message}"); continue; } progressBar.Value = idx + 1; Application.DoEvents(); } // 合并数据并保存 if (allData.Count == 0) { MessageBox.Show("无有效数据可合并", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 创建合并后的Excel文件 using (var outputPackage = new OfficeOpenXml.ExcelPackage()) { var outputSheet = outputPackage.Workbook.Worksheets.Add("合并结果"); // 写入表头 for (int col = 0; col < headers.Count; col++) { outputSheet.Cells[1, col + 1].Value = headers[col]; } int currentRow = 2; int totalRows = 0; // 合并所有数据 foreach (var table in allData) { foreach (System.Data.DataRow row in table.Rows) { for (int col = 0; col < headers.Count; col++) { outputSheet.Cells[currentRow, col + 1].Value = row[col]; } currentRow++; totalRows++; } } // 保存文件 outputPackage.SaveAs(new FileInfo(outputFile)); Log($"合并完成!文件路径: {outputFile}"); Log($"总行数: {totalRows} | 总列数: {headers.Count}"); MessageBox.Show($"合并成功!\n文件:{outputFile}\n行数:{totalRows}", "完成", MessageBoxButtons.OK, MessageBoxIcon.Information); } } catch (Exception ex) { Log($"保存失败: {ex.Message}"); MessageBox.Show($"保存文件失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void Log(string msg) { txtLog.AppendText($"{msg}\r\n"); txtLog.ScrollToCaret(); Application.DoEvents(); } } }