如何实现占满逻辑

我有一个需求,就是处理 word,对 word 中有 {ZM} 这个占位符的地方,插入空行,直到占满一整页,类似这个 word:
1.docx (12.9 KB)

处理后,变成这样:
2.docx (13.3 KB)

请问有什么比较方便的方法吗

@myboy Because MS Word 没有页面概念,您可以使用 LayoutCollector 来实现这一点。有几种方法可以使用。

1:

Document doc = new Document("input.docx");

FindReplaceOptions replaceOptions = new FindReplaceOptions();
replaceOptions.setReplacingCallback(new ReplaceWithLineFeed());

doc.getRange().replace("{ZM}", "", replaceOptions);

doc.save("output.docx");

class ReplaceWithLineFeed implements IReplacingCallback {
    public int replacing(ReplacingArgs e) throws Exception {
        // This is a Run node that contains either the beginning or the complete match.
        Run currentNode = (Run) e.getMatchNode();
        currentNode.setText(ControlChar.LINE_FEED);

        Document doc = (Document) currentNode.getDocument();
        Cell tableCell = (Cell) currentNode.getAncestor(NodeType.CELL);

        DocumentBuilder builder = new DocumentBuilder(doc);
        builder.moveTo(tableCell.getLastParagraph());
        Table parentTable = (Table)tableCell.getAncestor(NodeType.TABLE);

        LayoutCollector lc = new LayoutCollector(doc);
        while (lc.getStartPageIndex(parentTable.getLastRow()) != 2) {
            builder.writeln();
            lc.clear();
            doc.updatePageLayout();
        }
        tableCell.getLastParagraph().remove();

        // Signal to the replace engine to do nothing because we have already done all what we wanted.
        return ReplaceAction.SKIP;
    }
}

2:

Document doc = new Document("input.docx");

DocumentBuilder builder = new DocumentBuilder(doc);

Cell tableCell = null;
NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true);
for (Paragraph paragraph : (Iterable<Paragraph>) paragraphs) {
    for (Run run : paragraph.getRuns()) {
        if (run.getText().contains("{ZM}")) {
            run.setText(ControlChar.LINE_FEED);
            tableCell = (Cell) run.getAncestor(NodeType.CELL);
        }
    }
}

builder.moveTo(tableCell.getLastParagraph());
Table parentTable = (Table)tableCell.getAncestor(NodeType.TABLE);

LayoutCollector lc = new LayoutCollector(doc);
while (lc.getStartPageIndex(parentTable.getLastRow()) != 2) {
    builder.writeln();
    lc.clear();
    doc.updatePageLayout();
}
tableCell.getLastParagraph().remove();

doc.save("output.docx");

谢谢回复,我的情况可能会更加复杂,就是我不能确定 {ZM} 就一定是在 Table Cell 中,可能在文档的任意位置,根据你上面的思路,我修改了一下代码,确实能实现我的需求了,代码如下:

class ReplaceWithLineFeed implements IReplacingCallback {
    public int replacing(ReplacingArgs e) throws Exception {
        // This is a Run node that contains either the beginning or the complete match.
        Run currentNode = (Run) e.getMatchNode();

        Document doc = (Document)currentNode.getDocument();
        DocumentBuilder builder = new DocumentBuilder(doc);
        builder.moveTo(currentNode);

        doc.updatePageLayout();
        int initPageCount = doc.getPageCount();

        Paragraph paragraph = null;
        while (initPageCount == doc.getPageCount()) {
            paragraph = builder.insertParagraph();
            doc.updatePageLayout();
        }
        paragraph.remove();

        // Signal to the replace engine to do nothing because we have already done all what we wanted.
        return ReplaceAction.SKIP;
    }
}

十分感谢您提供的思路