Apache POI与XDOCREPORT替换占位符后转PDF报空指针异常
解决docx占位符替换后转PDF抛出NullPointerException的问题
我之前也碰到过一模一样的坑,原始docx能正常转PDF,但替换占位符后就直接炸了,排查下来主要是两个操作导致xdocreport解析文档时触发了空指针:
问题根源分析
多余的
doc.createStyles()调用
你代码里的doc.createStyles()会直接重置文档的样式集合,把原始docx里的内置样式全部清空重建。而xdocreport在转换PDF时严重依赖文档的原始样式信息,样式被清空后,转换过程中找不到对应的样式对象就会抛出NullPointerException。未处理空文本的边界情况
当r.getText(0)返回null时(比如某些空的文本run),StringSubstitutor.replace(text)会返回null,接着r.setText(replacedText, 0)会把这个run的文本设为null,这种异常的文本节点会让xdocreport的解析逻辑直接崩溃。
修复后的完整代码示例
// 读取待处理的docx文件 FileInputStream fis = new FileInputStream(COPIED); XWPFDocument doc = new XWPFDocument(fis); // 移除这行危险代码:doc.createStyles(); // 替换段落中的占位符 for (XWPFParagraph p : doc.getParagraphs()) { List<XWPFRun> runs = p.getRuns(); if (runs != null) { for (XWPFRun r : runs) { String text = r.getText(0); // 跳过空文本的run,避免设置null值 if (text == null) { continue; } StringSubstitutor substitutor = new StringSubstitutor(fieldsForReport); String replacedText = substitutor.replace(text); r.setText(replacedText, 0); } } } // 替换表格中的占位符 for (XWPFTable tbl : doc.getTables()) { for (XWPFTableRow row : tbl.getRows()) { for (XWPFTableCell cell : row.getTableCells()) { for (XWPFParagraph p : cell.getParagraphs()) { for (XWPFRun r : p.getRuns()) { String text = r.getText(0); if (text == null) { continue; } StringSubstitutor substitutor = new StringSubstitutor(fieldsForReport); String replacedText = substitutor.replace(text); r.setText(replacedText, 0); } } } } } // 保存修改后的文档,注意关闭输出流避免文件损坏 FileOutputStream fos = new FileOutputStream(COPIED); doc.write(fos); fos.close(); doc.close(); // 执行PDF转换 FileInputStream pdfFis = new FileInputStream(COPIED); XWPFDocument document = new XWPFDocument(pdfFis); PdfOptions options = PdfOptions.create(); PdfConverter converter = (PdfConverter) PdfConverter.getInstance(); converter.convert(document, new FileOutputStream(DEST), options); document.close(); pdfFis.close();
额外验证建议
- 替换保存后的docx文件,先手动用Word打开,确认文档没有损坏、样式正常显示
- 如果还是有问题,可以检查
fieldsForReport中的占位符是否包含特殊字符(比如换行、制表符),某些特殊格式可能会干扰xdocreport的解析逻辑
内容的提问来源于stack exchange,提问作者qvarky
相关产品推荐
相关产品推荐

