如何解决iText5调用pdfStamper.close()时的数组越界异常
从你的异常栈来看,问题出在CFF字体(Compact Font Format)的解析/子集化过程中,出现了索引越界。虽然你设置了BaseFont.NOT_EMBEDDED来避免字体嵌入导致PDF过大,但某些场景下iText5还是会触发字体处理逻辑,进而抛出这个异常。下面是具体的排查方向和解决方案:
可能的原因
这个异常通常和以下情况相关:
- 你使用的
AdobeFangsongStd-Regular.otf字体文件损坏或不完整,导致iText解析CFF表时出错; - 模板PDF本身包含有问题的嵌入式CFF字体,在flatten表单时触发了错误;
- iText5 5.5.13版本存在字体处理的潜在bug,尤其是在非嵌入字体的子集化逻辑上;
- 虽然你设置了
NOT_EMBEDDED,但某些操作间接触发了字体子集化流程。
具体解决方案
1. 检查并更换字体文件
首先确认AdobeFangsongStd-Regular.otf是完整、未损坏的字体文件。可以尝试替换为其他可靠的中文字体,比如系统自带的宋体:
// 替换为系统宋体,避免特定字体文件的问题 BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
如果更换字体后异常消失,说明原字体文件存在问题。
2. 显式关闭字体子集化
尝试在创建BaseFont时同时指定NOT_SUBSET参数,强制关闭字体子集化逻辑:
BaseFont bf = BaseFont.createFont("AdobeFangsongStd-Regular.otf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED | BaseFont.NOT_SUBSET);
虽然NOT_EMBEDDED理论上不会触发子集化,但显式关闭可以避免潜在的逻辑分支错误。
3. 升级iText5版本
你当前使用的是5.5.13版本,这个版本发布于2018年,后续的5.5.14版本修复了多个字体相关的bug。尝试升级到最新的iText5稳定版本(比如5.5.14),看看是否能解决这个异常。
4. 检查模板PDF的字体状态
用PDF阅读器(比如Adobe Acrobat)打开模板文件,查看字体属性:
- 确认模板中没有损坏的嵌入式字体;
- 如果模板中有嵌入式CFF字体,尝试重新生成模板,使用非嵌入式字体,避免在stamp过程中触发冲突的字体处理逻辑。
5. 调整表单flatten的时机
尝试将stamper.setFormFlattening(true)移到stamper.close()之前的更晚位置,确保所有内容绘制完成后再执行flatten:
// 先完成所有字段和表格的绘制 if (fieldMap != null) { // ... 你的字段填充逻辑 } if (tableMap != null) { // ... 你的表格填充逻辑 } // 最后设置flatten并关闭 stamper.setFormFlattening(true); stamper.close();
虽然这不一定直接解决问题,但可以确保flatten操作是在所有内容处理完成后执行,避免中间状态的冲突。
总结
这个异常大概率不是你的业务代码逻辑问题,而是iText5对特定字体或模板字体的处理bug,或者字体文件本身的问题。通过上述步骤逐一排查,应该能解决这个问题。
内容的提问来源于stack exchange,提问作者Wong.F.R

