用 Java 批量合并 Excel 工作簿,告别手动复制粘贴苦海

在日常报表、数据分析或文档管理工作中,经常需要把多个 Excel 工作簿合并到一起。无论是汇总月度报告、收集团队成员提交的数据,还是整理财务记录,用程序自动合并都比手动复制粘贴更高效、更不容易出错。

本文介绍两个实用的方法,使用 Spire.XLS for Java 来合并 Excel 文件:一是按工作表逐页复制整个工作簿,二是把多个工作表的数据汇总到一张总表里。

添加依赖库到项目

在项目中使用 Spire.XLS for Java,需要在构建配置中引入依赖。对于 Maven 项目,在 pom.xml 里加入以下内容:

<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <name>e-iceblue</name>
        <url>https://repo.e-iceblue.com/nexus/content/groups/public/</url>
    </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.xls</artifactId>
        <version>16.4.1</version>
    </dependency>
</dependencies>

刷新项目即可下载所需的 JAR 文件。该库要求 Java 8 或更高版本。注意:免费版对每个工作簿的工作表数量有限制,购买付费许可证可解除限制。

方法一:合并多个工作簿到同一个文件

这种方法会创建一个新的工作簿,然后把每个源文件中的工作表全部复制进去。addCopy() 方法可以保留原始工作表中的数据、单元格格式、公式和图表。

下面的示例将三个 Excel 文件合并为一个输出文件:

import com.spire.xls.*;

public class MergeExcelWorkbooks {
    public static void main(String[] args) {
        // 指定要合并的源文件路径列表
        String[] inputFiles = new String[]{
            "Budget_Summary.xlsx",
            "Income.xlsx",
            "Expenses.xlsx"
        };

        // 创建新工作簿,并清空默认的空工作表
        Workbook newBook = new Workbook();
        newBook.getWorksheets().clear();

        // 临时工作簿,用于逐个加载源文件
        Workbook tempBook = new Workbook();

        // 遍历每个源文件,复制所有工作表到新工作簿
        for (String file : inputFiles) {
            tempBook.loadFromFile(file);
            for (Worksheet sheet : (Iterable<Worksheet>) tempBook.getWorksheets()) {
                // addCopy 方法会复制整个工作表(包括格式、公式等)
                newBook.getWorksheets().addCopy(sheet, WorksheetCopyType.CopyAll);
            }
        }

        // 保存合并后的结果文件(Excel 2016 格式)
        newBook.saveToFile("MergedWorkbook.xlsx", ExcelVersion.Version2016);
        newBook.dispose();
        tempBook.dispose();
    }
}

代码说明:

  • getWorksheets().clear() 会删除新工作簿自带的空白页,让你从一个干净的起点开始。
  • loadFromFile() 将每个源文件加载到临时工作簿对象中。
  • addCopy() 配合 WorksheetCopyType.CopyAll 能够完整复制工作表,包括所有内容、样式和嵌入对象。

处理重名工作表: 如果多个源文件中存在同名的工作表(比如都叫“Sheet1”),库会自动给后面的工作表加上数字后缀,避免命名冲突。例如第二个“Sheet1”会变成“Sheet1(1)”。

方法二:将多个工作表的数据合并到一张表里

有些场景下,你希望把多个工作表的数据汇集到一个总表中,而不是保留为多个标签页。这种方法会复制数据区域,并依次追加到已有内容下方。

下面的例子把同一个工作簿中的两个工作表合并到第一个工作表里:

import com.spire.xls.*;

public class MergeWorksheetsIntoSingle {
    public static void main(String[] args) {
        // 加载源工作簿
        Workbook workbook = new Workbook();
        workbook.loadFromFile("input.xlsx");

        // 获取要合并的两个工作表(第1个和第2个)
        Worksheet sheet1 = workbook.getWorksheets().get(0);
        Worksheet sheet2 = workbook.getWorksheets().get(1);

        // 自动识别第二个工作表中实际有数据的区域
        CellRange sourceRange = sheet2.getAllocatedRange();

        // 计算目标位置:第一个工作表的最后一行 + 1 行
        CellRange destRange = sheet1.getCellRange(
            sheet1.getLastRow() + 1, 1
        );

        // 将源区域的数据复制到目标位置
        sourceRange.copy(destRange);

        // 删除已经复制完数据的第二个工作表(可选)
        sheet2.remove();

        // 保存合并后的结果
        workbook.saveToFile("MergedSheets.xlsx", ExcelVersion.Version2016);
        workbook.dispose();
    }
}

关键细节:

  • getAllocatedRange() 会自动检测包含实际数据的区域,无需硬编码行列范围。
  • 目标行位置通过 sheet1.getLastRow() + 1 计算,确保新数据紧跟在已有内容下方。
  • 复制完成后是否删除源工作表是可选的。如果希望保留原始工作表,可以省略 remove() 调用。

避免重复表头: 当追加多个工作表的数据时,每个源表可能都有自己的表头行。为了避免表头重复,可以在复制时调整源区域,排除第一行;或者只保留第一个工作表的表头,后续数据从第二行开始复制。

批量处理文件夹中的所有文件

如果需要处理大量文件,可以将方法一扩展成自动处理指定文件夹下的所有 Excel 文件:

import com.spire.xls.*;
import java.io.File;

public class MergeDirectory {
    public static void main(String[] args) {
        // 指定存放 Excel 文件的文件夹
        File folder = new File("excel_files/");
        // 筛选出 .xlsx 和 .xls 文件
        File[] files = folder.listFiles(
            (dir, name) -> name.endsWith(".xlsx") || name.endsWith(".xls")
        );

        // 创建新工作簿并清空默认工作表
        Workbook newBook = new Workbook();
        newBook.getWorksheets().clear();
        Workbook tempBook = new Workbook();

        // 遍历每个文件,复制所有工作表
        for (File file : files) {
            tempBook.loadFromFile(file.getAbsolutePath());
            for (Worksheet sheet : (Iterable<Worksheet>) tempBook.getWorksheets()) {
                newBook.getWorksheets().addCopy(sheet, WorksheetCopyType.CopyAll);
            }
        }

        // 保存合并后的文件
        newBook.saveToFile("MergedDirectory.xlsx", ExcelVersion.Version2016);
        newBook.dispose();
        tempBook.dispose();
    }
}

这种批量处理方式非常适合自动化报表生成、月度数据汇总等场景。

其他可用的 Java Excel 合并库

除了 Spire.XLS,还有其他几个 Java 库也能处理 Excel 文件合并,各有各的设计哲学和优缺点:

  • Apache POI:开源(Apache 2.0 许可),成熟且广泛使用,但在复制操作中需要手动处理样式和格式,才能保证效果一致。
  • EasyExcel:开源(Apache 2.0 许可),注重内存效率,采用流式处理,特别适合处理超大文件。
  • Aspose.Cells:商业许可,功能丰富,支持高级图表和格式处理,与 Spire.XLS 类似。

选择哪个库取决于你的项目预算、文件大小要求以及期望的 API 抽象程度。

总结

利用 Spire.XLS for Java 合并 Excel 文件主要有两种策略:使用 addCopy() 方法复制整个工作表(保留所有格式、公式和数据结构),或者通过复制数据区域将信息汇总到单个工作表。这两种方法都能处理常见问题,如重名工作表和表头管理,并且可扩展为基于目录的批量处理。库的 API 屏蔽了底层工作表复制的许多细节,不过在用于生产环境前,需要注意免费版对工作表数量的限制。想深入了解,可以查阅库的官方文档,其中还涵盖了处理不一致表头、合并前进行格式转换(如 CSV 转 Excel)以及合并后调整样式等进阶场景。

类似文章