解析 word 内嵌文件名中文乱码

Apache POI 简介是用 Java 编写的免费开源的跨平台的 Java API,Apache POI 提供 API 给 Java 程式对 Microsoft Office(Excel、WORD、PowerPoint、Visio 等)格式档案读和写的功能。POI 为 “Poor Obfuscation Implementation” 的首字母缩写,意为 “可怜的模糊实现”。
官方主页: http://poi.apache.org/index.html
API 文档: http://poi.apache.org/apidocs/index.html
问题发现
我们知道 word 是支持插入其他文件的
插入后入下图所示
在使用 Apache POI 过程中发现在读取文件名时会发生乱码问题
问题定位
经过代码排查定位发现文件名是取自一个 label
的元素值,
label
是在包 org.apache.poi.poifs.filesystem.Ole10Native
的第 165 行,代码如下
1 | case parsed: { |
继续跟踪源码进入 StringUtil.getFromCompressedUnicode
方法中,其代码中明确写出二进制目标编码为 ISO_8859_1
,
1 | /** |
问题解决
通过在 IDEA 的 debug 运算中发现将编码修改为 GBK
正常转换中文,看来这里是乱码的根本原因了,后续又新建文件测试,发现 wps、word2019、wps linux、永中 office 新建的文件在此处改为 GBK
均可正常显示中文文件名。问题成功定位,接下来进行代码修改
将源码拉取到本地,在 StringUtil 中添加如下方法,这里自定义了一个 charset, 我们在调用处调用这个方法就可以了,这样也能保证不会干扰其他代码
1 | public static String getFromCompressedUnicode( |
调用处 (Ole10Native)
修改
1 | label = StringUtil.getFromCompressedUnicode(data, ofs, len - 1,Charset.forName("GBK")); |
上传到私有仓库
我们公司是有自己的私有仓库的,既然改好了,就将代码上传上去吧
打开上一级的 build.gradle
在 subprojects
中添加
1 | apply plugin: 'maven-publish' |
引用修改后包
需要实际引用项目在 IDEA 右侧 gradle 中搜索一下那些包额外引用了 org.apache.poi
,需要手动排除掉
然后引入我们刚才修改的包就可以了
- 标题: 解析 word 内嵌文件名中文乱码
- 作者: tsvico
- 创建于 : 2021-08-21 16:52:07
- 更新于 : 2021-08-21 17:27:49
- 链接: https://blog.tbox.fun/2021/3213641848.html
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。