背景
最近在一个项目中,需要使用 EasyExcel 把一些带下划线和十六进制格式(形如 xB9f0)的文本写到 Excel 里。结果发现,导出的 Excel 文件中,这段文本会被 Apache POI 自动识别并转换成相应的 Unicode 字符,而不是按原样显示。翻来覆去地调试版本、升级到 FastExcel 后,问题依然存在。因为时间紧迫,我借助了前几天刚开通的 Trae Pro(Claude-4-Sonnet),很快就找到了症结,并最终提交了一个有效的 PR 到 FastExcel 的仓库。
排查过程
发现BUG
相信 Java 开发工程师如果接触过 Excel 的业务,都使用过 阿里巴巴开源的 EasyExcel
EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。 他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。
最近作者手上有个简单的不能再简单的 Excel导出任务。本来以为很简单,但是提测后,测试同事反馈导出的文件有问题:部分字符显示错误。具体的情况是:
当写入
_xB9f0_
这样的字符串到单元格时,打开 Excel 后看不到原本的_xB9f0_
,而是对应的 Unicode 字符(例如 "輰" 之类)

测试同事反馈后,由于最初用的是 EasyExcel,我首先就怀疑是不是版本太低,但是看了版本更新日志,没有涉及到这部分的改动或者BUG修复,按理说应该不是 EasyExcel的锅。 但是 出于对 EasyExcel 可能存在 BUG 的怀疑,我随即把依赖换成 FastExcel,因为 FastExcel 在功能上与 EasyExcel 基本一致,且社区维护活跃,问题有望得到修复。结果升级后,问题照旧,一点儿作用没有。
翻源码排查
进行了版本升级还是能够复现这个问题,那么可以断定:问题并非 EasyExcel
自身逻辑所导致,而是底层 Apache POI 对 _xHHHH_
这一模式内建的处理规则所致。
在 FastExcel 源码中,写入单元格时对 Apache POI 进行了二次封装发现最终还是调用了 Cell#setCellValue(String)
。也就是说,值实质上还是交给 Aapache-poi
来处理。这说明,FastExcel 并没有在写入字符串时对特殊模式进行识别与转义,完全依赖于 POI 的默认逻辑。 在 POI 的源码里,对字符串有一些特殊的转义规则:
Office Open XML 规范里规定:形如 xHHHH(其中 HHHH 是 4 位十六进制数字)的文本,会被视作"Unicode 转义序列"。也就是说,这段格式本身就是给 XML 里的特殊字符准备的转义写法。
Apache POI 在写入时,会检查单元格里的字符串,如果符合这种 xHHHH 模式,就把它当成转义序列直接转换成对应的 Unicode 字符。
于是,当字符串严格符合 _xHHHH_
模式时,POI 会自动替换为实际字符。如果我们希望在 Excel 中原样显示 xB9f0,就必须避免 POI 将其识别为"转义序列"。
Trae 紧急救火
因为项目交付时间紧张,想到前几天刚开通了 Trae Pro 的权限,因此尝试将把问题描述和代码片段贴给 Trae Pro(Claude-4-Sonnet)。
中间经过了几轮的修改问题,Trae 给出了正确的方向:

Trae 给出的排查思路
- Trae Pro 首先对 OOXML 规范进行了准确引用
"在 Office Open XML 规范中,形如 xHHHH 的文本会被视作对 Unicode 字符的转义写法。因此,直接调用 cell.setCellValue("xB9f0") 时,POI 会将其解析为对应的 Unicode 字符。"
- 接着,Trae 给出了"二次转义"的思路
- 先对
_xHHHH_
做"二次转义"。也就是说,要在交给 POI 前,把_xB9f0_
先变成\_xB9f0\_
这种"假装要输出 \ 的形式"。这样 POI 就不会把它当成真正的转义序列,而是按原样输出。
java
/**
* 将 "_xHHHH_" 格式的字符串前后各加一个反斜杠,
* 让 Apache POI 不再把它当成 Unicode 转义序列处理。
*/
private String escapeUnicodePattern(String value) {
if (value == null) {
return null;
}
// 捕获所有形如 _x1234_(4 位十六进制)的片段
return value.replaceAll("(_x[0-9A-Fa-f]{4}_)", "\\$1\\");
}
验证效果
事实证明 Trae 给出的效果很好!数据这下正常显示了出来。

尝试提交PR
在本地验证了 Trae 给出的"二次转义"方案完全可行后,我准备把这套"预处理 + 还原"的逻辑内嵌到 FastExcel 代码里,让最终用户在使用 FastExcel 导出类似 _xHHHH_
模式的字符串时无需自行编写转义逻辑,只需直接调用 FastExcel 提供的新方法即可。 这里我依然使用 Trae 进行多次询问,同时增加对应的测试用例。
在本地验证无误后,将改动推到自己 fork 的 fastexcel 仓库,生成一个 PR,详细描述了我这个PR修改的内容。在确认没有异议后, 这个PR合并到了 master 分支中,下个版本的 FastExcel 就能看到对应的方法啦!
使用心得
在处理这个不常见的BUG里,我能快速定位并快速修复,大部分功劳要归功于 Trae Pro。经过几天的使用,同事对比市面上几款常见的代码辅助工具,我的体验是:
- Trae 拥有全中文界面,对于我这样日常中英文混合阅读代码,但提问习惯更偏中文的开发者非常友好;
- 这种特别特殊的BUG,人力排查太麻烦了,真的需要 Trae 这种工具来辅助处理;
- 在对话里,我可以先抛出"为什么写
_xB9f0_
会被转义"的问题,Trae 给出规范引用和原理解释;接着我再追问"怎么绕过 POI 自动转义",Trae 自然衔接,给出示例代码;最后再问"把示例怎么放到 FastExcel 里更合适",Trae 也给了具体思路。整个过程像在跟一个经验丰富的同事一起头脑风暴,丝毫不觉得割裂; - 相比某些大厂的 Copilot、ChatGPT 付费版本,Trae 的订阅费用更亲民(我订阅的时候首月只要 3$)。对于想要"先试水"各种 AI 代码辅助工具的个人开发者或小团队,Trae Pro 性价比更高。
最后,Trae 也并非万能。比如在一些非常底层、需要查看具体源码才好定位的问题时,还是需要自己动手看 POI 源码、翻文档。但是在初步思路验证、示例代码生成、逻辑梳理方面,Trae Pro 的效率相当可观。