I´m using Apache poi library with java 11. I´m trying to see the track changes after to add a new text into a paragraph in a word document:
private void setSectionRun(XWPFParagraph paragraph){
// insert xml node
paragraph.getCTP().addNewIns().setAuthor("Kane");
XWPFRun newRun = paragraph.createRun();
newRun.setText(". Hello world");
paragraph.addRun(newRun);
}
And I get the following output in document.xml. In this case the track changes is not working:
<w:ins w:author="Kane"/>
<w:r>
<w:t>. Hello world</w:t>
</w:r>
In any case, if I manually edit the document I can see the track changes and accept or reject the insertion with the following result:
<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>
The problem is that I can't activate the track changes when I insert a new text in a paragraph with Apache poi.
On the other hand, with newRun.getCTR().getRPr().addNewRPrChange().setAuthor("Kane")
the format changes of a XWPFRun
are detected and I can see the change control correctly, but not the new text insertions at the paragraph level.
Is there a way to enable the track change on new text inserts?
Thanks in advance.
CodePudding user response:
Apache POI does not support tracking changes up to now.
As you see in your XML, your code places an empty w:ins
element above the w:r
element. But Microsoft Word wraps the w:r
element with the w:ins
element. The w:r
element is a child element of the w:ins
element.
One possibility to code that would be having a class XWPFInsRun
which extends XWPFRun
and a method to create such XWPFInsRun
in a XWPFParagraph
. Doing this one has all options of XWPFRun
extended by the options of CTRunTrackChange
- author and date for example.
Complete example:
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
}
}