为段落添加批注,并且有位置选区,先贴个图看添加后的效果
你需要了解的事
- 将文件docx扩展名修改为zip,你打开后可以看到下图的结构
添加批注后的格式如下,<w:p> 表示文档段落,可以看到该标签下面有 <w:commentRangeStart>、<w:commentRangeEnd>、<w:commentReference> 标签,分别对应的是 批注的起始位置、批注的结束位置、批注在commentsExtended.xml文件中的引用
理解了以上的东西,再来看下面的代码
public void addCommentToParagraph(XWPFParagraph paragraph, String text) {
BigInteger cursorId = nextCursorId();
CTComment ctComment = comments.addNewComment();
ctComment.setAuthor("test");
ctComment.setInitials("AR");
ctComment.setDate(new GregorianCalendar(Locale.CHINA));
ctComment.addNewP().addNewR().addNewT().setStringValue(text);
ctComment.setId(cursorId);
CTMarkupRange ctMarkupRange = paragraph.getCTP().addNewCommentRangeStart();
ctMarkupRange.setId(cursorId);
Node beginNode = paragraph.getRuns().get(0).getCTR().getDomNode();
paragraph.getCTP().getDomNode().insertBefore(ctMarkupRange.getDomNode(), beginNode);
paragraph.getCTP().addNewCommentRangeEnd().setId(cursorId);
paragraph.getCTP().addNewR().addNewCommentReference().setId(cursorId);
}
<w:commentRangeStart>、<w:commentRangeEnd>、<w:commentReference> 标签中都有 w:id 属性,需要确保这个属性是全局唯一的
- nextCursorId() 用于获取下一个不重复的批注ID
- 设置批注信息与内容
- 获取段落的开始位置,把 <w:commentRangeStart> 标签插入到段落前
- 插入 <w:commentRangeEnd>、<w:commentReference> 标签
其中 nextCursorId() 方法实现可以参考如下代码
private final Set<BigInteger> commentIdSet;
private BigInteger cursorId = new BigInteger("23100000");
public DocumentComments(XWPFDocument document) {
XWPFComments docComments = document.getDocComments();
if (docComments == null) {
docComments = document.createComments();
}
comments = docComments.getCtComments();
commentIdSet = comments.getCommentList().stream().map(CTMarkup::getId).collect(Collectors.toSet());
}
private BigInteger nextCursorId() {
while (commentIdSet.contains(cursorId)) {
cursorId = cursorId.add(BigInteger.ONE);
}
commentIdSet.add(cursorId);
return cursorId;
}
本文结束