使用 Java 高效管理 Excel 批注:添加、读取、修改和删除

在 Excel 中整理数据时,有些信息不适合直接放进单元格,例如价格调整的原因、异常数据的说明,或者需要后续确认的事项。这些内容可以通过批注附加到对应的单元格,而不影响单元格原有的数据。

如果需要给多个单元格添加说明,或者读取和清理已有批注,也可以通过 Java 完成。

本文介绍四种操作:添加批注、读取批注、修改批注和删除批注。

一、添加 Maven 依赖

首先,在 Java 项目的 pom.xml 文件中添加以下仓库和依赖:

xml 复制代码
<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <name>e-iceblue</name>
        <url>https://repo.e-iceblue.cn/repository/maven-public/</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.xls.free</artifactId>
        <version>16.3.1</version>
    </dependency>
</dependencies>

二、给 Excel 单元格添加批注

要给单元格添加批注,可以使用 CellRange.addComment() 方法。该方法返回一个 ExcelComment 对象,通过 setText() 即可设置批注内容。

下面以一份简单的销售数据表 sales.xlsx 为例:

商品 数量 单价 金额
产品 A 20 49 980
产品 B 15 60 900

假设这些数据位于工作表的 A1:D3 区域。我们希望给 C2 单元格添加价格说明,并给 D3 单元格添加一条待核实的备注。

完整代码如下:

java 复制代码
import com.spire.xls.*;

public class AddExcelComments {

    public static void main(String[] args) {

        // 创建 Workbook 对象
        Workbook workbook = new Workbook();

        try {
            // 加载 Excel 文件
            workbook.loadFromFile("sales.xlsx");

            // 获取第一个工作表
            Worksheet sheet = workbook.getWorksheets().get(0);

            // 给 C2 单元格添加批注
            ExcelComment comment1 =
                    sheet.getCellRange("C2").addComment();

            comment1.setText("该产品单价已于本月调整。");

            // 设置批注框大小
            comment1.setWidth(220);
            comment1.setHeight(60);

            // 默认不展开显示批注框
            comment1.setVisible(false);

            // 给 D3 单元格添加批注
            ExcelComment comment2 =
                    sheet.getCellRange("D3").addComment();

            comment2.setText("请核实该金额是否准确。");
            comment2.setAutoSize(true);

            // 保存结果
            workbook.saveToFile(
                    "sales-with-comments.xlsx",
                    ExcelVersion.Version2016);

        } finally {
            workbook.dispose();
        }
    }
}

运行后,程序会生成 sales-with-comments.xlsx,其中 C2 和 D3 单元格分别包含对应的批注。

这里用到了几个方法:

  • addComment():为指定单元格添加批注。
  • setText():设置批注内容。
  • setWidth() 和 setHeight():调整批注框的宽度和高度。
  • setAutoSize(true):让批注框根据文字内容自动调整大小。
  • setVisible(false):设置批注框默认不展开显示。

需要注意,setVisible(false) 并不是删除批注,只是控制批注框的显示状态。在支持传统批注的 Excel 桌面版本中,通常仍然可以通过对应的单元格查看批注内容。

三、读取 Excel 中的批注

如果需要检查某份 Excel 文件中是否存在批注,或者提取批注内容,可以通过 Worksheet.getComments() 获取工作表中的批注集合。

然后遍历集合,通过 getText() 读取批注文字,也可以使用 getRow() 和 getColumn() 查看批注所在的单元格位置。

下面读取上一节生成的 sales-with-comments.xlsx,输出其中所有批注的信息。

java 复制代码
import com.spire.xls.*;

public class ReadExcelComments {

    public static void main(String[] args) {

        Workbook workbook = new Workbook();

        try {
            // 加载 Excel 文件
            workbook.loadFromFile(
                    "sales-with-comments.xlsx");

            // 获取第一个工作表
            Worksheet sheet = workbook.getWorksheets().get(0);

            // 获取批注数量
            int count = sheet.getComments().getCount();

            System.out.println("批注数量:" + count);

            // 遍历工作表中的所有批注
            for (int i = 0; i < count; i++) {

                ExcelComment comment =
                        sheet.getComments().get(i);

                // 读取批注位置及内容
                System.out.println("批注 " + (i + 1));
                System.out.println("行:" + comment.getRow());
                System.out.println("列:" + comment.getColumn());
                System.out.println("内容:" + comment.getText());
                System.out.println("----------------");
            }

        } finally {
            workbook.dispose();
        }
    }
}

程序会输出批注数量,以及每条批注所在的行、列和文字内容。

如果只需要读取某个单元格的批注,也可以直接通过 getComment() 获取:

java 复制代码
ExcelComment comment =
        sheet.getCellRange("C2").getComment();

if (comment != null) {
    System.out.println(comment.getText());
}

与遍历整个批注集合相比,这种写法更适合已知单元格位置的情况。

需要注意,某些单元格可能没有批注,因此读取前最好判断返回值是否为 null,避免空指针异常。

四、修改 Excel 单元格中的批注

批注添加后,如果数据发生变化,也可以直接修改已有批注,而不需要删除后重新创建。

例如,销售表中 C2 单元格的单价已经确认,可以将原来的"该产品单价已于本月调整"修改为"当前单价已核实,无需调整"。

可以通过 getComment() 获取已有批注,再调用 setText() 更新内容。

完整代码如下:

java 复制代码
import com.spire.xls.*;

public class ModifyExcelComment {

    public static void main(String[] args) {

        Workbook workbook = new Workbook();

        try {
            // 加载包含批注的 Excel 文件
            workbook.loadFromFile(
                    "sales-with-comments.xlsx");

            // 获取第一个工作表
            Worksheet sheet = workbook.getWorksheets().get(0);

            // 获取 C2 单元格的批注
            ExcelComment comment =
                    sheet.getCellRange("C2").getComment();

            // 修改批注内容
            if (comment != null) {

                comment.setText(
                        "当前单价已核实,无需调整。");

                // 调整批注框大小
                comment.setAutoSize(true);
            }

            // 保存修改后的文件
            workbook.saveToFile(
                    "sales-modified-comments.xlsx",
                    ExcelVersion.Version2016);

        } finally {
            workbook.dispose();
        }
    }
}

这里,getComment() 返回的是单元格已有的批注对象,setText() 会更新该对象的文字内容。

运行后,程序将生成 sales-modified-comments.xlsx。C2 单元格的批注会被更新,但单元格中的价格数据不会改变。

除了修改文字,还可以调整批注框的大小、显示状态以及文字格式。

如果只想修改说明内容,使用 setText() 就足够了。

五、删除 Excel 单元格中的批注

当某项说明已经不再需要时,可以通过 ExcelComment.remove() 方法删除对应的批注。

例如,假设 D3 单元格中的金额已经核实,不需要继续保留"请核实该金额是否准确"这条批注。

可以先获取 D3 单元格的批注,然后调用 remove()。

java 复制代码
import com.spire.xls.*;

public class DeleteExcelComment {

    public static void main(String[] args) {

        Workbook workbook = new Workbook();

        try {
            // 加载包含批注的 Excel 文件
            workbook.loadFromFile(
                    "sales-with-comments.xlsx");

            // 获取第一个工作表
            Worksheet sheet = workbook.getWorksheets().get(0);

            // 获取 D3 单元格的批注
            ExcelComment comment =
                    sheet.getCellRange("D3").getComment();

            // 删除批注
            if (comment != null) {
                comment.remove();
            }

            // 保存结果
            workbook.saveToFile(
                    "sales-removed-comment.xlsx",
                    ExcelVersion.Version2016);

        } finally {
            workbook.dispose();
        }
    }
}

执行后,D3 单元格中的批注将被删除,而单元格原有的金额数据会保留。

remove() 只删除指定批注,不会清空单元格的值,也不会删除其他单元格上的批注。

如果需要删除多个批注,可以先确定目标单元格,再逐个调用 getComment().remove()。删除前同样应检查批注是否存在。

六、使用时需要注意的问题

1. 传统批注和新版 Excel 批注不是同一回事

本文使用的 ExcelComment 对应传统的单元格批注。在较新的 Microsoft Excel 版本中,这类内容通常称为"备注(Notes)"。

新版 Excel 中支持回复、@提及等功能的线程式批注(Threaded Comments)属于不同的机制,不能直接认为本文的代码也适用于这类批注。

2. 添加批注前检查单元格是否已有批注

对已经存在批注的单元格,如果只是希望更新文字,应该优先使用 getComment() 和 setText()。

这样可以避免重复创建批注,也便于保留已有对象的其他设置。

3. 修改和删除操作不会自动保存文件

无论是修改批注内容还是删除批注,都需要调用 workbook.saveToFile() 保存结果。

本文将处理结果保存为新文件,避免直接覆盖原始数据。如果要修改原文件,建议先备份。

相关推荐
txxzjmzlh几秒前
SpringBoot 统⼀功能处理
java·spring boot·后端
nice_lcj5202 小时前
Java Lambda 表达式入门:怎么写、怎么用、常用方法有哪些
java·开发语言·后端·面试
码农小河662 小时前
基于SSM+JSP+MySQL的在线医疗服务系统的设计与实现
java·开发语言·mysql
SL_staff3 小时前
从配置失效到逻辑复用:JVS-Logic 如何构建可治理的业务编排中枢
java·spring·产品
特立独行的猫A3 小时前
一份 Markdown 发十个平台:cspub 一稿多投
java·后端·python
文丑颜不良啊4 小时前
LeetCode1961~1980题目解析
java·leetcode
文丑颜不良啊5 小时前
LeetCode2001~2020题目解析
java·leetcode
用户3721574261355 小时前
Java 批量提取 Word 文档中的图片并保存到本地
java
SL_staff5 小时前
BI项目失败率90%?JVS如何用三阶闭环构建可落地的数据生产力平台
java·开源·全栈
nice_lcj5207 小时前
ThreadLocal 入门:它是怎么隔离数据的、为什么会导致内存泄漏
java·开发语言·后端·面试·并发编程·内存泄漏·threadlocal