如何解决Apache POI添加带图片页眉后标题页图片消失的问题
问题原因
- 核心问题是
CTSectPr节属性的配置时机错误:在插入正文内容之前就添加了节属性并开启了标题页配置,后续调用createHeader生成页眉时,POI会更新节属性配置,导致标题页图片的资源引用关系被破坏,所以图片无法渲染。 - 次要问题:图片输入流使用后未关闭,可能引发资源占用异常。
修正方案
调整CTSectPr的配置位置,将其移到所有正文内容插入完成之后、创建页眉之前,同时补充输入流的关闭逻辑,修正后完整代码如下:
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import org.apache.poi.xwpf.usermodel.*; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr; import org.apache.poi.util.Units; import org.apache.poi.wp.usermodel.HeaderFooterType; public class Check { public static void main(String[] args) throws Exception { XWPFDocument document = new XWPFDocument(); XWPFParagraph paragraph = document.createParagraph(); // 插入标题页图片 File image = new File("D:\\Img.png"); FileInputStream imageData = new FileInputStream(image); XWPFRun run = paragraph.createRun(); int imageType = XWPFDocument.PICTURE_TYPE_PNG; String imageFileName = image.getName(); int width = 612; int height = 550; run.addPicture(imageData, imageType, imageFileName, Units.toEMU(width), Units.toEMU(height)); imageData.close(); // 用完关闭输入流 // 插入第一页正文 paragraph = document.createParagraph(); run = paragraph.createRun(); run.setText("The Body... first page"); // 插入分页符和第二页正文 paragraph = document.createParagraph(); run = paragraph.createRun(); run.addBreak(BreakType.PAGE); run.setText("The Body... second page"); // 节属性配置移到此处,所有正文内容写完之后再配置 CTSectPr sectPr = document.getDocument().getBody().addNewSectPr(); sectPr.addNewTitlePg(); // 配置标题页页眉 XWPFHeader firstHeader = document.createHeader(HeaderFooterType.FIRST); paragraph = firstHeader.createParagraph(); paragraph.setAlignment(ParagraphAlignment.CENTER); run = paragraph.createRun(); run.setText("First page header content..."); // 配置默认页眉(非标题页显示) XWPFHeader defaultHeader = document.createHeader(HeaderFooterType.DEFAULT); paragraph = defaultHeader.getParagraphArray(0); if (paragraph == null) paragraph = defaultHeader.createParagraph(); paragraph.setAlignment(ParagraphAlignment.RIGHT); File headerImage = new File("D:\\Picture.png"); FileInputStream headerImageData = new FileInputStream(headerImage); run = paragraph.createRun(); imageType = XWPFDocument.PICTURE_TYPE_PNG; imageFileName = headerImage.getName(); width = 100; height = 50; run.addPicture(headerImageData, imageType, imageFileName, Units.toEMU(width), Units.toEMU(height)); headerImageData.close(); // 用完关闭输入流 // 保存文档 FileOutputStream out = new FileOutputStream("D:\\CreateWordFooters.docx"); document.write(out); out.close(); document.close(); } }
补充说明
如果需要标题页不显示页眉,可以直接不配置HeaderFooterType.FIRST对应的页眉内容即可,开启titlePg后标题页默认不会继承默认页眉的配置。
内容的提问来源于stack exchange,提问作者Kiran Gavhane
相关产品推荐
相关产品推荐

