// Create comment
BigInteger cId = getCommentId(comments);
ctComment = comments.addNewComment();
ctComment.setAuthor("John Smith");
ctComment.setInitials("JS");
ctComment.setDate(new GregorianCalendar(Locale.getDefault()));
ctComment.addNewP().addNewR().addNewT().setStringValue("Test Comment");
ctComment.setId(cId);
// Set CommentRangeStart
String uri = CTMarkupRange.type.getName().getNamespaceURI();
String localPart = "commentRangeStart";
// XmlCursor cursor = p.getCTP().newCursor();
XmlCursor cursor = r.getCTR().newCursor();
cursor.toFirstChild();
cursor.beginElement(localPart, uri);
cursor.toParent();
CTMarkupRange commentRangeStart = (CTMarkupRange) cursor.getObject(); // This line throws a ClassCastException error
cursor.dispose();
commentRangeStart.setId(cId);
// Set CommentRangeEnd and CommentReference
p.getCTP().addNewCommentRangeEnd().setId(cId);
// p.getCTP().addNewR().addNewCommentReference().setId(cId);
r.getCTR().addNewCommentReference().setId(cId);
for(XWPFParagraph p:paragraphs){
List<XWPFRun> runs = p.getRuns();
if (runs.size() > 0) {
for (XWPFRun r : runs) {
String text = r.getText(0);
for (Map.Entry<String, List<String>> entry : rules.entrySet()) {
String key = entry.getKey();
List<String> value = entry.getValue();
for (int i = 0; i < value.size(); i++) {
if (text != null && regexContains(text, value.get(i))) {
// Create comment
BigInteger cId = getCommentId(comments);
ctComment = comments.addNewComment();
ctComment.setAuthor("John Smith");
ctComment.setInitials("JS");
ctComment.setDate(new GregorianCalendar(Locale.getDefault()));
ctComment.addNewP().addNewR().addNewT().setStringValue(key);
ctComment.setId(cId);
// New snippet from Axel Richter
p.getCTP().addNewCommentRangeStart().setId(cId);
p.getCTP().addNewCommentRangeEnd().setId(cId);
p.getCTP().addNewR().addNewCommentReference().setId(cId);
}
}
}
}
}
}
这并不像你想象的那么难。
若要对段落内的运行进行注释,需要在段落中的文本运行开始之前设置注释范围start。在段落中文本运行结束后,需要设置注释范围结束。这正是我的代码示例已经完成的。当然,我的代码示例中的所有段落都只运行了一个文本。
在下面的完整示例中,第二个注释仅注释单词“second”。为此,该段有三个文本运行。第一个有文本“段落与”,第二个有文本“第二”并有注释,第三个有文本“注释”。
import java.io.*;
import org.apache.poi.*;
import org.apache.poi.ooxml.*;
import org.apache.poi.openxml4j.opc.*;
import org.apache.xmlbeans.*;
import org.apache.poi.xwpf.usermodel.*;
import static org.apache.poi.ooxml.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import javax.xml.namespace.QName;
import java.math.BigInteger;
import java.util.GregorianCalendar;
import java.util.Locale;
public class CreateWordWithComments {
//a method for creating the CommentsDocument /word/comments.xml in the *.docx ZIP archive
private static MyXWPFCommentsDocument createCommentsDocument(XWPFDocument document) throws Exception {
OPCPackage oPCPackage = document.getPackage();
PackagePartName partName = PackagingURIHelper.createPartName("/word/comments.xml");
PackagePart part = oPCPackage.createPart(partName, "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml");
MyXWPFCommentsDocument myXWPFCommentsDocument = new MyXWPFCommentsDocument(part);
String rId = "rId" + (document.getRelationParts().size()+1);
document.addRelation(rId, XWPFRelation.COMMENT, myXWPFCommentsDocument);
return myXWPFCommentsDocument;
}
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument();
MyXWPFCommentsDocument myXWPFCommentsDocument = createCommentsDocument(document);
CTComments comments = myXWPFCommentsDocument.getComments();
CTComment ctComment;
XWPFParagraph paragraph;
XWPFRun run;
//first comment
BigInteger cId = BigInteger.ZERO;
ctComment = comments.addNewComment();
ctComment.setAuthor("Axel Ríchter");
ctComment.setInitials("AR");
ctComment.setDate(new GregorianCalendar(Locale.US));
ctComment.addNewP().addNewR().addNewT().setStringValue("The first comment.");
ctComment.setId(cId);
paragraph = document.createParagraph();
paragraph.getCTP().addNewCommentRangeStart().setId(cId); //comment range start is set before text run
run = paragraph.createRun();
run.setText("Paragraph with the first comment.");
paragraph.getCTP().addNewCommentRangeEnd().setId(cId); //comment range end is set after text run
paragraph.getCTP().addNewR().addNewCommentReference().setId(cId);
//paragraph without comment
paragraph = document.createParagraph();
run = paragraph.createRun();
run.setText("Paragraph without comment.");
//second comment
cId = cId.add(BigInteger.ONE);
ctComment = comments.addNewComment();
ctComment.setAuthor("Axel Ríchter");
ctComment.setInitials("AR");
ctComment.setDate(new GregorianCalendar(Locale.US));
ctComment.addNewP().addNewR().addNewT().setStringValue("The second comment. Comments the word \"second\".");
ctComment.setId(cId);
paragraph = document.createParagraph();
run = paragraph.createRun();
run.setText("Paragraph with the ");
paragraph.getCTP().addNewCommentRangeStart().setId(cId); //comment range start is set before text run
run = paragraph.createRun();
run.setText("second");
paragraph.getCTP().addNewCommentRangeEnd().setId(cId); //comment range end is set after text run
run = paragraph.createRun();
run.setText(" comment.");
paragraph.getCTP().addNewR().addNewCommentReference().setId(cId);
//write document
FileOutputStream out = new FileOutputStream("CreateWordWithComments.docx");
document.write(out);
out.close();
document.close();
}
//a wrapper class for the CommentsDocument /word/comments.xml in the *.docx ZIP archive
private static class MyXWPFCommentsDocument extends POIXMLDocumentPart {
private CTComments comments;
private MyXWPFCommentsDocument(PackagePart part) throws Exception {
super(part);
comments = CommentsDocument.Factory.newInstance().addNewComments();
}
private CTComments getComments() {
return comments;
}
@Override
protected void commit() throws IOException {
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
xmlOptions.setSaveSyntheticDocumentElement(new QName(CTComments.type.getName().getNamespaceURI(), "comments"));
PackagePart part = getPackagePart();
OutputStream out = part.getOutputStream();
comments.save(out, xmlOptions);
out.close();
}
}
}
我无法使用ApachePOI删除docx文件中的所有注释。有没有其他方法可以使用docx4j api删除注释?
我正在尝试创建一个包含多列的word文档。这样做(而不是使用表)的原因是,数据将跨越多个页面,在添加到新页面之前,我只能用列填充整个页面。 可以用ApachePOI实现吗?谢谢
问题内容: 我使用Python-docx生成Microsoft Word文档。用户在编写以下内容时希望这样做:“大家早上好,这是我的%(profile_img)s,您喜欢吗?” 在一个HTML字段,我创建一个Word文档,我recuper用户的图片从数据库和i。由所述用户的图片替换键字%(profile_img)■ 不能在文件的结尾 。对于Python-docx,我们使用以下指令添加图片: 图片添
我需要在表中的特定字段中添加两个不同的单词。 表是: 所以首先我需要选择我想要修改的记录: 假设结果是10条记录。 我现在有两个变量var1和var2 我现在需要将var1添加到表的field2的50%,将var2添加到其他50% 我该怎么做呢? 例子: 表: 第1条第2条 从mytable中选择*字段3=1 将返回2个字段。。。 下一个 将String1插入到50%的结果中,并将String2插
我试图设置一些段落或文本在. docx文件使用Apache POI,我正在读取一个. docx文件作为模板从WEB-INF/资源/模板文件夹内我的战争文件,一旦读取,我想创建动态更多的表后,第9表用作模板,我可以添加更多的表格,但其他类型的内容(段落)被安排在文档的其他部分?有必要的形式来做这件事吗?
问题内容: 通过使用文件中的以下代码块 我能够生成具有以下文件内容的文件 我想知道如何在生成的文件中添加评论?例如,生成的属性应具有以下内容: 我如何使用Ant来动态地做到这一点? 问题答案: 不支持编写带有多个注释的属性文件。为什么呢 PropertyFile.java ant属性文件任务由一个类支持,该类使用store()方法存储注释。从任务中仅提取一条注释,并将其传递给类以保存到文件中。 解