如何在不丢失格式的情况下使用POI替换“ .docx”中的书签?

时间:2019-05-09 10:16:20

标签: java apache-poi

我正在尝试将书签替换为值。

peer channel join block_name.block

我能够将书签替换为值,但它与书签文本的格式(字体系列,字体大小,颜色等)不一样。

任何人都可以提供一些建议。

1 个答案:

答案 0 :(得分:0)

如前所述,我相信这是您的确切用例,官方存档链接 help请着重使用 Node styleNode 复制样式信息。

    /**
     * Replace the text - if any - contained between the bookmarkStart and
it's
     * matching bookmarkEnd tag with the text specified. The technique used
will
     * resemble that employed when inserting text after the bookmark. In
short,
     * the code will iterate along the nodes until it encounters a matching
     * bookmarkEnd tag. Each node encountered will be deleted unless it is
the
     * final node before the bookmarkEnd tag is encountered and it is a
     * character run. If this is the case, then it can simply be updated to
     * contain the text the users wishes to see inserted into the document.
If
     * the last node is not a character run, then it will be deleted, a new
run
     * will be created and inserted into the paragraph between the
bookmarkStart
     * and bookmarkEnd tags.
     *
     * @param run An instance of the XWPFRun class that encapsulates the
text
     * that is to be inserted into the document following the bookmark.
     */
    private void replaceBookmark(XWPFRun run) {
        Node nextNode = null;
        Node styleNode = null;
        Node lastRunNode = null;
        Node toDelete = null;
        NodeList childNodes = null;
        Stack<Node> nodeStack = null;
        boolean textNodeFound = false;
        boolean foundNested = true;
        int bookmarkStartID = 0;
        int bookmarkEndID = -1;
        int numChildNodes = 0;

        nodeStack = new Stack<Node>();
        bookmarkStartID = this._ctBookmark.getId().intValue();
        nextNode = this._ctBookmark.getDomNode();
        nodeStack.push(nextNode);

        // Loop through the nodes looking for a matching bookmarkEnd tag
        while (bookmarkStartID != bookmarkEndID) {
            nextNode = nextNode.getNextSibling();
            nodeStack.push(nextNode);

            // If an end tag is found, does it match the start tag? If so,
end
            // the while loop.
            if (nextNode.getNodeName().contains(Bookmark.BOOKMARK_END_TAG))
{
                try {
                    bookmarkEndID = Integer.parseInt(
                            nextNode.getAttributes().getNamedItem(
                            Bookmark.BOOKMARK_ID_ATTR_NAME).getNodeValue());
                } catch (NumberFormatException nfe) {
                    bookmarkEndID = bookmarkStartID;
                }
            }
            //else {
                // Place a reference to the node on the nodeStack
            //    nodeStack.push(nextNode);
            //}
        }

        // If the stack of nodes found between the bookmark tags is not
empty
        // then they have to be removed.
        if (!nodeStack.isEmpty()) {

            // Check the node at the top of the stack. If it is a run, get
it's
            // style - if any - and apply to the run that will be replacing
it.
            //lastRunNode = nodeStack.pop();
            lastRunNode = nodeStack.peek();
            if ((lastRunNode.getNodeName().equals(Bookmark.RUN_NODE_NAME)))
{
                styleNode = this.getStyleNode(lastRunNode);
                if (styleNode != null) {
                    run.getCTR().getDomNode().insertBefore(
                            styleNode.cloneNode(true),
run.getCTR().getDomNode().getFirstChild());
                }
            }