Apache poi:在段落中插入文本并在word文档中查看轨迹变化

Apache poi: insert text in a paragraph and view track changes in a word document

我将 Apache poi 库与 java 11 一起使用。我正在尝试查看将新文本添加到 word 文档中的段落后的音轨变化:

 private void setSectionRun(XWPFParagraph paragraph){
    // insert xml node
    paragraph.getCTP().addNewIns().setAuthor("Kane");

    XWPFRun newRun = paragraph.createRun();
    newRun.setText(". Hello world");
    paragraph.addRun(newRun);
}

我在 document.xml 中得到以下输出。在这种情况下,音轨更改不起作用:

<w:ins w:author="Kane"/>
<w:r>
    <w:t>. Hello world</w:t>
</w:r>

无论如何,如果我手动编辑文档,我可以看到轨道更改并接受或拒绝插入,结果如下:

<w:ins w:id="0" w:author="Kane" w:date="2022-04-20T15:33:00Z">
    <w:r w:rsidR="00B00A22">
        <w:t>. Hello world</w:t>
    </w:r>
</w:ins>

问题是当我使用 Apache poi 在段落中插入新文本时无法激活曲目更改。

另一方面,newRun.getCTR().getRPr().addNewRPrChange().setAuthor("Kane") 检测到 XWPFRun 的格式更改,我可以正确看到更改控件,但看不到段落级别的新文本插入。

有没有办法在新的文本插入中启用音轨更改?

提前致谢。

Apache POI 目前不支持跟踪更改。

如您在 XML 中所见,您的代码在 w:r 元素上方放置了一个空的 w:ins 元素。但是 Microsoft Word 将 w:r 元素包装在 w:ins 元素中。 w:r 元素是 w:ins 元素的子元素。

编码的一种可能性是 class XWPFInsRun 扩展 XWPFRun 和在 XWPFParagraph 中创建这样的 XWPFInsRun 的方法。执行此操作会将 XWPFRun 的所有选项都扩展为 CTRunTrackChange 的选项 - 例如作者和日期。

完整示例:

import java.io.FileOutputStream;

import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

public class CreateWordInsRun {
    
 static XWPFInsRun createInsRun(XWPFParagraph paragraph, String author, java.util.Calendar date) {
  CTRunTrackChange trackChange = paragraph.getCTP().addNewIns();
  trackChange.setAuthor(author);
  trackChange.setDate(date);
  trackChange.addNewR();
  return new XWPFInsRun(
    trackChange,
    trackChange.getRArray(0),
    paragraph
   );
 }

 public static void main(String[] args) throws Exception {

  XWPFDocument doc = new XWPFDocument();

  XWPFParagraph paragraph = doc.createParagraph();
  XWPFRun run = paragraph.createRun();
  run.setText("Paragraph 1");

  paragraph = doc.createParagraph();
  XWPFInsRun insRun = createInsRun(paragraph, "Kane", new java.util.GregorianCalendar());
  insRun.setText("Paragraph 2 inserted by Kane");
  System.out.println(insRun.getAuthor());
  System.out.println(insRun.getDate());
  
  paragraph = doc.createParagraph();
  run = paragraph.createRun();
  run.setText("Paragraph 3");
    
  FileOutputStream out = new FileOutputStream("./WordDocument.docx");
  doc.write(out);
  out.close();
  doc.close();    
 }
 
 static class XWPFInsRun extends XWPFRun {
  private CTRunTrackChange trackChange;
  public XWPFInsRun(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);   
  }
  //... further methods
 }
}