比如我想在这个文本中的这两个字添加批注,
image.png (4.8 KB)
@humanhuman, 这是一个如何做到这一点的例子:
Document doc = new Document("in.docx");
FindReplaceOptions options = new FindReplaceOptions();
options.setReplacingCallback(new FindReplaceHandler());
doc.getRange().replace("股份", "", options);
doc.stopTrackRevisions();
doc.save("out.docx");
static class FindReplaceHandler implements IReplacingCallback {
public int replacing(ReplacingArgs e) throws Exception {
Node currentNode = e.getMatchNode();
// The first (and may be the only) run can contain text before the match,
// in this case it is necessary to split the run.
if (e.getMatchOffset() > 0)
currentNode = SplitRun((Run)currentNode, e.getMatchOffset());
// This array is used to store all nodes of the match for further removing.
ArrayList runs = new ArrayList();
// Find all runs that contain parts of the match string.
int remainingLength = e.getMatch().group().length();
while ((remainingLength > 0) &&
(currentNode != null) &&
(currentNode.getText().length() <= remainingLength))
{
runs.add(currentNode);
remainingLength = remainingLength - currentNode.getText().length();
// Select the next Run node.
// Have to loop because there could be other nodes such as BookmarkStart etc.
do
{
currentNode = currentNode.getNextSibling();
}
while ((currentNode != null) && (currentNode.getNodeType() != NodeType.RUN));
}
// Split the last run that contains the match if there is any text left.
if ((currentNode != null) && (remainingLength > 0))
{
SplitRun((Run)currentNode, remainingLength);
runs.add(currentNode);
}
Document doc =(Document) e.getMatchNode().getDocument();
Run startRun = (Run)runs.get(0);
Run endRun = (Run)runs.get(runs.size() - 1);
Comment comment = new Comment(doc, "My Name", "MN", new Date());
comment.getParagraphs().add(new Paragraph(doc));
comment.getFirstParagraph().getRuns().add(new Run(doc, "Comment text."));
CommentRangeStart commentRangeStart = new CommentRangeStart(doc, comment.getId());
CommentRangeEnd commentRangeEnd = new CommentRangeEnd(doc, comment.getId());
startRun.getParentNode().insertBefore(commentRangeStart, currentNode);
endRun.getParentNode().insertAfter(commentRangeEnd, currentNode);
commentRangeEnd.getParentNode().insertAfter(comment, commentRangeEnd);
//Signal to the replace engine to stop after the first replacement.
return ReplaceAction.STOP;
}
private static Run SplitRun(Run run, int position)
{
((Document)run.getDocument()).stopTrackRevisions();
Run afterRun = (Run)run.deepClone(true);
afterRun.setText(run.getText().substring(position));
run.setText(run.getText().substring((0), (0) + (position)));
run.getParentNode().insertAfter(afterRun, run);
((Document)run.getDocument()).startTrackRevisions("My Name");
return afterRun;
}
}
in.docx (12.2 KB)
请查看我们的文档以获取更多详细信息:
@humanhuman, 您可以使用正则表达式查找不同段落中的文本。 请检查更新后的代码:
Document doc = new Document("in.docx");
FindReplaceOptions options = new FindReplaceOptions();
options.setReplacingCallback(new FindReplaceHandler());
String stringPattern = "股份";
doc.getRange().replace(stringPattern, "", options);
String regex = "过[^开]+开";
Pattern p = Pattern.compile(regex);
doc.getRange().replace(p, "", options);
doc.stopTrackRevisions();
doc.save("out.docx");
static class FindReplaceHandler implements IReplacingCallback {
public int replacing(ReplacingArgs e) throws Exception {
Node currentNode = e.getMatchNode();
// The first (and may be the only) run can contain text before the match,
// in this case it is necessary to split the run.
if (e.getMatchOffset() > 0)
currentNode = SplitRun((Run)currentNode, e.getMatchOffset());
// This array is used to store all nodes of the match for further removing.
ArrayList runs = new ArrayList();
// Find the length of the found text.
char[] chars = e.getMatch().group().toCharArray();
int remainingLength = 0;
for (char c: chars) {
if (c != '\uE00D') {
remainingLength++;
}
}
// Find all runs that contain parts of the match string.
while (
(remainingLength > 0) &&
(currentNode != null) &&
(currentNode.getText().length() <= remainingLength))
{
runs.add(currentNode);
remainingLength = remainingLength - currentNode.getText().length();
// Select the next Run node.
// Have to loop because there could be other nodes such as BookmarkStart etc.
do
{
Node prevNode = currentNode;
currentNode = currentNode.getNextSibling();
if (currentNode == null) {
Paragraph curParagraph = (Paragraph)prevNode.getParentNode();
// If the current node is the last in the paragraph, get the first run of the next paragraph.
if (curParagraph.getLastChild() == prevNode) {
Paragraph nextParagraph = (Paragraph)curParagraph.getNextSibling();
currentNode = nextParagraph.getFirstChild();
}
}
}
while ((currentNode != null) && (currentNode.getNodeType() != NodeType.RUN));
}
// Split the last run that contains the match if there is any text left.
if ((currentNode != null) && (remainingLength > 0))
{
SplitRun((Run)currentNode, remainingLength);
runs.add(currentNode);
}
Document doc =(Document) e.getMatchNode().getDocument();
Run startRun = (Run)runs.get(0);
Run endRun = (Run)runs.get(runs.size() - 1);
Comment comment = new Comment(doc, "My Name", "MN", new Date());
comment.getParagraphs().add(new Paragraph(doc));
comment.getFirstParagraph().getRuns().add(new Run(doc, "Comment text."));
CommentRangeStart commentRangeStart = new CommentRangeStart(doc, comment.getId());
CommentRangeEnd commentRangeEnd = new CommentRangeEnd(doc, comment.getId());
startRun.getParentNode().insertBefore(commentRangeStart, startRun);
endRun.getParentNode().insertAfter(commentRangeEnd, endRun);
commentRangeEnd.getParentNode().insertAfter(comment, commentRangeEnd);
//Signal to the replace engine to do nothing because we have already done all what we wanted.
return ReplaceAction.STOP;
}
private static Run SplitRun(Run run, int position)
{
((Document)run.getDocument()).stopTrackRevisions();
Run afterRun = (Run)run.deepClone(true);
afterRun.setText(run.getText().substring(position));
run.setText(run.getText().substring((0), (0) + (position)));
run.getParentNode().insertAfter(afterRun, run);
((Document)run.getDocument()).startTrackRevisions("My Name");
return afterRun;
}
}
out.docx (11.4 KB)