Apache POI:如何在段落指定位置插入带修订的Run?
问题分析
你的代码直接调用paragraph.getCTP().addNewIns()会将修订节点默认追加到段落末尾,且光标操作未正确定位到目标Run的位置,导致新Run总是出现在段落最后。
解决方案
要实现插入到指定位置,需先定位到目标Run对应的XML节点,再在该节点之后插入带修订的Ins节点。以下是修改后的完整代码:
修改后的核心代码
private void insertCTRun(List<XWPFParagraph> paraList){ for (XWPFParagraph paragraph : paraList) { List<XWPFRun> runs = paragraph.getRuns(); // 修正原代码的变量名错误 // 遍历段落中的Run for (int i = 0; i < runs.size(); i++) { XWPFRun r = runs.get(i); String text = r.getText(0); // 定位包含目标文本的Run if (text != null && text.contains("TextToFind")) { // 获取当前Run对应CTR节点的光标 XmlCursor cursor = r.getCTR().newCursor(); // 将光标移动到当前节点的下一个位置(即目标Run之后) cursor.toNextSibling(); // 在光标指定位置插入带修订的新Run XWPFTrackRun newCTRun = createInsRun(paragraph, cursor, SummaryCommonConstants.NAME_APP, new java.util.GregorianCalendar()); newCTRun.setText("NewText"); // 插入后刷新Run列表,避免后续遍历出现索引异常 runs = paragraph.getRuns(); } } } } // 修改修订节点创建逻辑,通过光标插入到指定位置 private static XWPFTrackRun createInsRun(XWPFParagraph paragraph, XmlCursor cursor, String author, java.util.Calendar date) { CTRunTrackChange trackChange = CTRunTrackChange.Factory.newInstance(); trackChange.setAuthor(author); trackChange.setDate(date); CTR run = trackChange.addNewR(); // 将修订节点插入到光标指定的位置 cursor.insertElement(trackChange); cursor.dispose(); // 释放光标资源 return new XWPFTrackRun(trackChange, run, paragraph); } // 保留你的XWPFTrackRun类不变 public class XWPFTrackRun extends XWPFRun { private CTRunTrackChange trackChange; public XWPFTrackRun(CTRunTrackChange trackChange, CTR run, IRunBody p) { super(run, p); this.trackChange = trackChange; } public String getAuthor() { return this.trackChange.getAuthor(); } public void setAuthor(String author) { this.trackChange.setAuthor(author); } public java.util.Calendar getDate() { return this.trackChange.getDate(); } public void setDate(java.util.Calendar date) { this.trackChange.setDate(date); } }
关键修改说明
- 修正变量错误:原代码中
p.getRuns()的p未定义,改为paragraph.getRuns()。 - 精准定位光标:获取目标Run的
CTR节点光标,移动到该节点的下一个兄弟位置,确保插入位置在目标Run之后。 - 光标插入节点:不再使用默认追加的
addNewIns(),而是通过XmlCursor.insertElement()将修订节点插入到指定位置。 - 刷新Run列表:插入新Run后重新获取段落的Run列表,避免后续遍历出现索引异常。
修改后,带修订的NewText会被正确插入到TextToFind所在Run的后方。
内容的提问来源于stack exchange,提问作者Kane
相关产品推荐
相关产品推荐

