使用 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() 保存结果。

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

相关推荐
福兮说2 小时前
AI 把工号整理成 Excel 后,前面的 0 还在吗?我会先核对这三列
excel
ydjs678899-bot2 小时前
为什么大型monorepos变慢了Rush.js + Sparo对此做了什么
开发语言·javascript·ecmascript
const_qiu2 小时前
第 2.5 章 2.5.8:质量关 —— 安全审查、UI/UX 审查与踩坑复盘
java·人工智能·安全·ui·ux
坊钰2 小时前
【LangGraph框架入门级】12. 人机交互:interrupt 中断与 Command 恢复
开发语言·数据库·python·人机交互·ai编程·langgraph
chde2Wang2 小时前
hadoop部署错误-namenode address dfs.namenode.servicerpc-address not configured
java·大数据·hadoop
开开心心就好2 小时前
打印机卡住打不了?一键清理卡死打印队列
服务器·开发语言·算法·pdf·ocr·idea·visual studio code
David猪大卫2 小时前
【C++修炼】STL容器—模板进阶:非类型模板参数、模板特化、模板分离编译
c语言·开发语言·c++·经验分享·笔记·学习·面试
牛战士coding2 小时前
Java 对象写入 Redis 后类型变了?Jackson 多态序列化问题复盘
java·开发语言·redis
小白的码BUG之路2 小时前
Jenkins -- 配置jdk和maven
java·jenkins·maven