POI从4.x升级至5.x后方法缺失问题求助
Apache POI 4.x升级到5.x后方法缺失问题的解决方案
问题概述
升级Apache POI从4.x到5.x后,代码出现多个方法/枚举缺失报错,涉及:
CTR.isSetRPr()、CTRPr.isSetRFonts()方法不存在CTRPr.getShd()方法无法找到STOnOff.TRUE枚举无法引用
相关报错代码片段:
字体样式设置代码:
private static void setHeaderAndFooterXWPFRunStyle(XWPFRun r1, String font, int fontSize) { r1.setFontSize(fontSize); CTRPr rpr = r1.getCTR().isSetRPr() ? r1.getCTR().getRPr() : r1.getCTR().addNewRPr(); CTFonts fonts = rpr.isSetRFonts() ? rpr.getRFonts() : rpr.addNewRFonts(); fonts.setAscii(font); fonts.setEastAsia(font); fonts.setHAnsi(font); }
阴影设置相关代码:
CTShd cTShd = pr.getShd(); STOnOff.TRUE
切回4.x版本后所有功能正常。
依赖问题分析
POI 5.x对OOXML Schema依赖做了重大调整:
- 不再使用单独的
ooxml-schemas包,拆分出poi-ooxml-full(完整Schema支持)和poi-ooxml-lite(精简版),两者不可同时引入,否则会导致类冲突。 - 你的5.x依赖同时引入了
poi-ooxml-full和poi-ooxml-lite,这是核心问题之一。 - XMLBeans版本从3.x升级到5.x,生成的Schema代码结构变化,比如
isSetXxx()方法被移除,枚举类的访问方式调整。
解决方案
1. 修正依赖配置
保留poi-ooxml-full(需要完整Schema支持时),移除poi-ooxml-lite和重复的poi-ooxml(poi-ooxml-full已包含该依赖),同时无需单独引入xmlbeans(poi-ooxml-full已自带适配版本)。
正确的5.x依赖示例(Gradle):
implementation 'org.apache.poi:poi:5.2.3' implementation 'org.apache.poi:poi-ooxml-full:5.2.3'
2. 调整代码适配API变化
字体样式设置代码修改
移除isSetXxx()方法,改用getXxx() != null判断节点是否存在:
private static void setHeaderAndFooterXWPFRunStyle(XWPFRun r1, String font, int fontSize) { r1.setFontSize(fontSize); CTR ctr = r1.getCTR(); // 替换isSetRPr()为getRPr() != null CTRPr rpr = ctr.getRPr() != null ? ctr.getRPr() : ctr.addNewRPr(); // 替换isSetRFonts()为getRFonts() != null CTFonts fonts = rpr.getRFonts() != null ? rpr.getRFonts() : rpr.addNewRFonts(); fonts.setAscii(font); fonts.setEastAsia(font); fonts.setHAnsi(font); }
更优方案:使用POI高层API替代底层CT类操作,避免依赖底层Schema变化:
private static void setHeaderAndFooterXWPFRunStyle(XWPFRun r1, String font, int fontSize) { r1.setFontSize(fontSize); r1.setFontFamily(font); }
阴影设置代码修改
- 替换
getShd()的空判断,不存在则创建新节点 - 调整
STOnOff.TRUE的引用方式(XMLBeans 5.x生成的枚举需通过内部Enum类访问)
示例代码:
// 确保导入正确的包:org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff CTRPr pr = ...; // 你的CTRPr实例 CTShd cTShd = pr.getShd(); if (cTShd == null) { cTShd = pr.addNewShd(); } // 替换STOnOff.TRUE为STOnOff.Enum.TRUE cTShd.setVal(STOnOff.Enum.TRUE);
内容的提问来源于stack exchange,提问作者Tizliu
相关产品推荐
相关产品推荐

