使用docx4j查找节点元素的拥有部分

时间:2014-11-07 10:06:58

标签: java docx4j

我的DOCX文档中有一个占位符列表,我已经用这种方式引用了:

private void findPlaceHolders() {
    Docx4JPlaceHolderFinder finder = new Docx4JPlaceHolderFinder();
    TraversalUtil.visit(document, false, finder);
    placeHoldersRegister = new HashMap<>(finder.getFoundPlaceHolders());
}

Docx4JPlaceHolderFinderCallbackImpl的一个实现,找到包含此表单文本值的所有ContentAccessor(主要是R)实例: $ [placeholder_name]

placeHolderRegisterHashMap<String, List<ContentAccessor>>的一个实例;它将ContentAccessor个实例的列表与其对应的占位符关键字相关联。

我希望能够在这些占位符中插入图片。以下是我的Docx4JImageMailMerger类的完整源代码:

package org.johndoe.fwk.simplefile.implementation.docxutil;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.docx4j.TraversalUtil;
import org.docx4j.dml.wordprocessingDrawing.Inline;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;
import org.docx4j.wml.ContentAccessor;
import org.docx4j.wml.Drawing;
import org.docx4j.wml.ObjectFactory;

import org.johndoe.fwk.exception.ExceptionFwk;

/**
 * Classe dédiée au publipostage d'image dans un document Docx4J.
 */
public class Docx4JImageMailMerger {

    private final ObjectFactory factory;
    private WordprocessingMLPackage document;
    private Map<String, List<ContentAccessor>> placeHoldersRegister;

    public Docx4JImageMailMerger(WordprocessingMLPackage document) {
        this.factory = new ObjectFactory();
        this.document = document;
    }

    public void setImage(String placeHolderName, File imageFile) {
        setImage(placeHolderName, imageFile, null);
    }

    public void setImage(String placeHolderName, File imageFile, Long width) {
        List<ContentAccessor> placeHolders = selectPlaceHolders(placeHolderName);

        for (ContentAccessor placeHolder : placeHolders) {
            cleanPlaceHolder(placeHolder);
            includeImage(placeHolder, imageFile, width);
        }
    }

    private List<ContentAccessor> selectPlaceHolders(String imageName) {
        if (placeHoldersRegister == null)
            findPlaceHolders();

        List<ContentAccessor> selectedPlaceHolders = new ArrayList<>();
        selectedPlaceHolders.addAll(placeHoldersRegister.get(imageName));
        return selectedPlaceHolders;
    }

    private void findPlaceHolders() {
        Docx4JPlaceHolderFinder finder = new Docx4JPlaceHolderFinder();
        TraversalUtil.visit(document, false, finder);
        placeHoldersRegister = new HashMap<>(finder.getFoundPlaceHolders());
    }

    private void cleanPlaceHolder(ContentAccessor placeHolder) {
        placeHolder.getContent().clear();
    }

    private void includeImage(ContentAccessor placeHolder, File imageFile, Long width) {
        try {
            Part part = getOwningPart(placeHolder);
            BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(document, part, imageFile);

            Inline inline;
            if (width == null)
                inline = imagePart.createImageInline(imageFile.getName(), "test", 0, 1, false);
            else
                inline = imagePart.createImageInline(imageFile.getName(), "test", 0, 1, width, false);

            Drawing drawing = factory.createDrawing();
            drawing.getAnchorOrInline().add(inline);
            placeHolder.getContent().add(drawing);

        } catch (Exception e) {
            throw new ExceptionFwk("Erreur lors de l'inclusion de l'image", e);
        }
    }

    private Part getOwningPart(ContentAccessor placeHolder) {
        // What should I do here ?
    }

}

我不知道我的文档的哪一部分是选定的占位符:正文,页眉,页脚等。问题是我必须为BinaryPartAbstractImage.createImagePart(document, part, imageFile)确定它。

有什么方法可以获得我的元素所属的Part实例吗?

1 个答案:

答案 0 :(得分:1)

一般来说,假设有P对象,您可以调用getParent来查找其父对象。

但这些物品并不知道它们与哪个部分相关联。

当您第一次使用Docx4JPlaceHolderFinder找到占位符时,您将需要记录找到它们的部分。或者改变你的方法来逐步完成处理。