【问题标题】:Insert a line break inside a paragraph in XWPFDocument在 XWPFDocument 的段落内插入换行符
【发布时间】:2013-01-27 15:33:30
【问题描述】:

我正在使用 apache poi 3.8 将值写入 word 模板。我用所需的值替换 word 文件(键)中的特定字符串,例如word 文档有一段包含键 %Entry1%,我想用“Entry text line1 \nnew line”替换它。在我的实现中,所有替换的键和值都存储在 Map 中。

Map<String, String> replacedElementsMap;

HWPFDocument 的代码是:

Range range = document.getRange();
for(Map.Entry<String, String> entry : replacedElementsMap.entrySet()) {
            range.replaceText(entry.getKey(), entry.getValue());
}

此代码运行良好,我只需将 \n 放入输入字符串中即可换行。但是我找不到 XWPFDocument 的类似方法。我当前的 XWPFDocument 代码是:

List<XWPFParagraph> xwpfParagraphs = document.getParagraphs();
for(XWPFParagraph xwpfParagraph : xwpfParagraphs) {
            List<XWPFRun> xwpfRuns = xwpfParagraph.getRuns();
            for(XWPFRun xwpfRun : xwpfRuns) {
                String xwpfRunText = xwpfRun.getText(xwpfRun.getTextPosition());
                for(Map.Entry<String, String> entry : replacedElementsMap.entrySet()) {
                    if (xwpfRunText != null && xwpfRunText.contains(entry.getKey())) {
                        xwpfRunText = xwpfRunText.replaceAll(entry.getKey(), entry.getValue());
                    }
                }
                xwpfRun.setText(xwpfRunText, 0);
            }
        }

现在“\n”字符串不会导致回车,如果我使用xwpfRun.addCarriageReturn();,我只会在段落后换行。我应该如何在 xwpf 中正确创建新行?

【问题讨论】:

  • 如果您在 Office 的段落中添加换行符,然后查看生成的 XML,这是否提供了所需内容的线索?
  • XML 确实包含换行符,但我希望在每个换行符之后有一个新的换行符,所以最后我不得不手动创建新的段落。

标签: java apache apache-poi xwpf


【解决方案1】:

我有另一个解决方案,而且更简单:

            if (data.contains("\n")) {
                String[] lines = data.split("\n");
                run.setText(lines[0], 0); // set first line into XWPFRun
                for(int i=1;i<lines.length;i++){
                    // add break and insert new text
                    run.addBreak();
                    run.setText(lines[i]);
                }
            } else {
                run.setText(data, 0);
            }

【讨论】:

  • 我使用了run.addCarriageReturn();,但不起作用。根据您的建议,更改为run.addBreak 后,工作正常。很好,但是……为什么?
  • addBreak() 似乎在运行结束时附加了一个中断。如果运行中已经有一些文本元素怎么办?是否有可能在两者之间添加一个休息时间?
【解决方案2】:

毕竟,我必须手动创建段落。基本上,我将替换字符串拆分为一个数组,并为每个数组元素创建一个新段落。代码如下:

protected void replaceElementInParagraphs(List<XWPFParagraph> xwpfParagraphs,
                                              Map<String, String> replacedMap) {
        if (!searchInParagraphs(xwpfParagraphs, replacedMap)) {
            replaceElementInParagraphs(xwpfParagraphs, replacedMap);
        }
    }

 private boolean searchInParagraphs(List<XWPFParagraph> xwpfParagraphs, Map<String, String> replacedMap) {
        for(XWPFParagraph xwpfParagraph : xwpfParagraphs) {
            List<XWPFRun> xwpfRuns = xwpfParagraph.getRuns();
            for(XWPFRun xwpfRun : xwpfRuns) {
                String xwpfRunText = xwpfRun.getText(xwpfRun.getTextPosition());
                for(Map.Entry<String, String> entry : replacedMap.entrySet()) {
                    if (xwpfRunText != null && xwpfRunText.contains(entry.getKey())) {
                        if (entry.getValue().contains("\n")) {
                            String[] paragraphs = entry.getValue().split("\n");
                            entry.setValue("");
                            createParagraphs(xwpfParagraph, paragraphs);
                            return false;
                        }
                        xwpfRunText = xwpfRunText.replaceAll(entry.getKey(), entry.getValue());
                    }
                }
                xwpfRun.setText(xwpfRunText, 0);
            }
        }
        return true;
    }

 private void createParagraphs(XWPFParagraph xwpfParagraph, String[] paragraphs) {
        if(xwpfParagraph!=null){
            for (int i = 0; i < paragraphs.length; i++) {
                XmlCursor cursor = xwpfParagraph.getCTP().newCursor();
                XWPFParagraph newParagraph = document.insertNewParagraph(cursor);
                newParagraph.setAlignment(xwpfParagraph.getAlignment());
                newParagraph.getCTP().insertNewR(0).insertNewT(0).setStringValue(paragraphs[i]);
                newParagraph.setNumID(xwpfParagraph.getNumID());
            }
            document.removeBodyElement(document.getPosOfParagraph(xwpfParagraph));
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-19
    • 1970-01-01
    • 2019-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多