话不多说直奔主题,近期工作中需要使用aspose来操作word文档来给文档中具体的某些文字增加批注,在网上查了相关资料,几乎都是无脑copy来copy去,特记录一下我解决问题的方式。
分为几种情况
1、给段落增加批注,这个比较简单,官方文档上也有对应的例子
public static void annotationForText(String inPath, String outPath) {
try {
init();
// Attached to post.
Document doc = new Document(inPath);
// Target parapraph for Comment anchor.
Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 9, true);
// Target Run for Comment anchor.
Run cmtAnchorRun = para.getRuns().get(10);
Comment cmt = new Comment(doc, "admin", "", new Date());
cmt.setText("This word is error");
para.appendChild(cmt);
para.insertBefore(new CommentRangeStart(doc, cmt.getId()), cmtAnchorRun);
para.insertAfter(new CommentRangeEnd(doc, cmt.getId()), cmtAnchorRun);
doc.save(outPath);
} catch (Exception e) {
log.error("----> Aspose.word create Comment with text Exception", e);
}
}
这里init()方法是加载license,这里就不写了,我这里用的是正版,不初始化的话会有水印
2、给段落中具体的文字增加批注
public static void addComment(Document doc) {
int begin = 15; //需要加批注的文字 第一个字的偏移量
int end = 19; //最后一个字的偏移量
int parIdx = 0; //段落号,注意这里doc的段落是从0段开始的
Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, paraIdx, true);
RunCollection runs = para.getRuns();
int midFlag = 0;
Comment cmt = new Comment(doc, "admin", "", new Date());
cmt.setText("这里是批注");
CommentRangeStart commentRangeStart = new CommentRangeStart(doc, cmt.getId());
CommentRangeEnd commentRangeEnd = new CommentRangeEnd(doc, cmt.getId());
int index = begin;//这个begin是你需要加批注的文字在这个段落里面的偏移量
for (int i = 0; i < runs.getCount(); i++) {
Run run = runs.get(i);
int length = run.getText().length();
midFlag = midFlag + length;
if (midFlag >= index) {
//此时批注未跨越run 拆分当前run 插入comment
// eg. midflag = 8 pos=[4,5]
Run beforeRun = (Run) run.deepClone(true); // 批注前的run
String text = run.getText();
int off = index - (midFlag - length);
beforeRun.setText(text.substring(0, off));
run.setText(text.substring(off)); //批注的run
run.getParentNode().insertBefore(beforeRun, run);
run.getParentNode().insertBefore(index == begin ? commentRangeStart : commentRangeEnd, run);
if (index == end) {
break;
}
index = end;
midFlag = midFlag - length + beforeRun.getText().length();
}
}
para.appendChild(cmt);
}
这里简单说明一下,word文档,把后缀改成压缩包的后缀,比如.zip是可以解压的,有兴趣的可以试一下
上面document.xml是主要的文件
可以看的到这里都是由一个个的<w:p>和<w:r>组成的,这个p就是对应的就是aspose里面的Paragraph类,r就是Run类,图片对应Shape类,可以看到如果对上面截图里的天天增加批注的话,它是在同一个run里面的,直接加的话,会加到run里,所以就需要给这个run拆分一下,对应拆分的代码我也贴在最上面了 deepClone,之后再拆分完的run前后增加CommentRangeStart和 CommentRangeEnd就可以了,这两个类是确定批注开始和结束位置使用的,增加结束之后,在段落尾部,append一下刚刚创建Comment对象就可以了。增加完批注的xml大概是下面这样的结构
这里需要注意的是。如果同时增加多个批注的话,可能会导致位置不准确,para.appendChild(comment)这一步,要在所有CommentRangeStart和 CommentRangeEnd都增加完以后再挨个的去添加。
暂时就先写这么多,转载请标明谢谢。