合并多个Excel文件,并且保持原表格的数字格式

如果你需要合并多个Excel文件,并且保持原表格的数字格式(如日期、货币、百分比等),可以使用 EPPlus(一个强大的.NET Excel操作库)。以下是完整的解决方案,使用C#和EPPlus实现。


方案概述

目标

  • 合并多个Excel文件(.xlsx)到一个文件。
  • 保留原格式(数字、日期、字体、颜色、边框等)。
  • 支持合并多个Sheet(可选)。

技术栈

  • C# + .NET Core(或.NET Framework)
  • EPPlus(开源库,支持Excel 2007+格式)
  • LINQ(用于文件遍历)

步骤 1:安装EPPlus

通过NuGet安装EPPlus:

Install-Package EPPlus -Version 5.8.8

(如果你用的是.NET Core 3.1+,可以直接用 Install-Package EPPlus,最新版已支持跨平台。)


步骤 2:完整代码

using OfficeOpenXml;
using System;
using System.IO;
using System.Linq;

class ExcelMerger
{
    static void Main(string[] args)
    {
        // 设置EPPlus许可证(社区版免费)
        ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

        // 输入文件夹(存放待合并的Excel文件)
        string inputFolder = @"C:\ExcelFiles\";
        // 输出文件(合并后的Excel)
        string outputFile = @"C:\MergedExcel.xlsx";

        // 获取所有Excel文件
        var excelFiles = Directory.GetFiles(inputFolder, "*.xlsx");

        // 创建一个新的Excel包(最终合并的文件)
        using (var mergedPackage = new ExcelPackage(new FileInfo(outputFile)))
        {
            // 遍历每个Excel文件
            foreach (var file in excelFiles)
            {
                using (var sourcePackage = new ExcelPackage(new FileInfo(file)))
                {
                    // 遍历当前Excel的所有Sheet
                    foreach (var sourceSheet in sourcePackage.Workbook.Worksheets)
                    {
                        // 在合并后的Excel中创建同名Sheet(如果已存在则追加数据)
                        string sheetName = sourceSheet.Name;
                        var targetSheet = mergedPackage.Workbook.Worksheets.FirstOrDefault(s => s.Name == sheetName);

                        if (targetSheet == null)
                        {
                            // 如果Sheet不存在,直接复制整个Sheet(保留格式)
                            targetSheet = mergedPackage.Workbook.Worksheets.Add(sheetName, sourceSheet);
                        }
                        else
                        {
                            // 如果Sheet已存在,仅复制数据(保留格式)
                            int targetRow = targetSheet.Dimension?.End.Row ?? 1; // 获取目标Sheet的最后一行
                            int sourceRowCount = sourceSheet.Dimension.Rows;
                            int sourceColCount = sourceSheet.Dimension.Columns;

                            // 复制数据(逐行逐列,保留格式)
                            for (int row = 1; row <= sourceRowCount; row++)
                            {
                                for (int col = 1; col <= sourceColCount; col++)
                                {
                                    // 复制单元格(值 + 格式)
                                    var sourceCell = sourceSheet.Cells[row, col];
                                    var targetCell = targetSheet.Cells[targetRow + row, col];

                                    // 复制值
                                    targetCell.Value = sourceCell.Value;

                                    // 复制样式(数字格式、字体、颜色等)
                                    targetCell.StyleID = sourceCell.StyleID; // 直接复用StyleID更高效
                                }
                            }
                        }
                    }
                }
            }

            // 保存合并后的Excel
            mergedPackage.Save();
            Console.WriteLine($"合并完成!文件已保存到: {outputFile}");
        }
    }
}

关键点解析

1. 保留数字格式

EPPlus通过 StyleID 直接复用原单元格的样式,确保:

  • 日期(yyyy-mm-dd
  • 货币($#,##0.00
  • 百分比(0.00%
  • 自定义格式等 完全保留

2. 合并逻辑

  • 如果Sheet不存在 → 直接复制整个Sheet(Add方法保留格式)。
  • 如果Sheet已存在 → 逐行逐列复制数据,并复制样式。

3. 性能优化

  • 使用 StyleID 而不是逐个设置样式属性,减少内存占用。
  • 按需调整 sourcePackagemergedPackage 的作用域,避免内存泄漏。

测试示例

输入文件1 (File1.xlsx)

A B C
2023-01-01 $100.00 50%
Product Price Qty

输入文件2 (File2.xlsx)

A B C
2023-02-01 $200.00 75%
Service Fee Count

合并后 (MergedExcel.xlsx)

A B C
2023-01-01 $100.00 50%
Product Price Qty
2023-02-01 $200.00 75%
Service Fee Count

格式完全保留!


扩展功能

1. 仅合并特定Sheet

if (sourceSheet.Name == "Sales")  // 只合并名为"Sales"的Sheet
{
    // 合并逻辑
}

2. 处理大数据量

  • 使用 ExcelRange.LoadFromArrays 批量写入数据。
  • 禁用公式计算加速处理:
    mergedPackage.Workbook.CalcMode = ExcelCalcMode.Manual;
    

3. 命令行工具

封装为.exe,支持参数输入:

ExcelMerger.exe -input "C:\Input" -output "C:\Output\Merged.xlsx"

结论

  • 适用场景:需要保留Excel格式的合并任务(如财务报告、数据汇总)。
  • 优势:EPPlus比NPOI更易用,比OpenXML更高效。
  • 你的技术栈:C# + EPPlus完全匹配,无需额外学习。

如果需要进一步优化(如异步处理、更复杂格式),可以继续扩展!

posted @ 2025-04-17 00:12  青山下  阅读(159)  评论(0)    收藏  举报