Как программно связать повторитель в таблице docx4j? - PullRequest
0 голосов
/ 17 февраля 2019

Я знаю об OpenDOPE.Когда я создаю абзац, обернутый тегом повторителя, это нормально.Когда я пытаюсь создать повторитель tr, обернутый таблицей, он выдает

org.docx4j.openpackaging.exceptions.Docx4JException: Problems applying bindings

at org.docx4j.model.datastorage.BindingTraverserXSLT.traverseToBind(BindingTraverserXSLT.java:237)
at org.docx4j.model.datastorage.BindingHandler.applyBindings(BindingHandler.java:292)
at org.docx4j.model.datastorage.BindingHandler.applyBindings(BindingHandler.java:216)
at org.docx4j.Docx4J.bind(Docx4J.java:554)

Но когда я сохраняю документ, а затем загружаю его с помощью Docx4J.load (), а затем связываю, что работает нормально.

РЕДАКТИРОВАТЬ Проблема возникает в XMLUtils.deepCopy sdtСодержание tr становится пустым

/*
         * Losing content here?
         * 
         * First, make absolutely sure that what you have is valid.
         * 

Результаты XmlUtils.marshaltoString (tbl);

<w:tbl xmlns:dsp="http://schemas.microsoft.com/office/drawing/2008/diagram" xmlns:cppr="http://schemas.microsoft.com/office/2006/coverPageProps" xmlns:odx="http://opendope.org/xpaths" xmlns:c14="http://schemas.microsoft.com/office/drawing/2007/8/2/chart" xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:odgm="http://opendope.org/SmartArt/DataHierarchy" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:dgm="http://schemas.openxmlformats.org/drawingml/2006/diagram" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture" xmlns:we="http://schemas.microsoft.com/office/webextensions/webextension/2010/11" xmlns:pvml="urn:schemas-microsoft-com:office:powerpoint" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:sl="http://schemas.openxmlformats.org/schemaLibrary/2006/main" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:comp="http://schemas.openxmlformats.org/drawingml/2006/compatibility" xmlns:b="http://schemas.openxmlformats.org/officeDocument/2006/bibliography" xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:xvml="urn:schemas-microsoft-com:office:excel" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:oda="http://opendope.org/answers" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:odc="http://opendope.org/conditions" xmlns:cdr="http://schemas.openxmlformats.org/drawingml/2006/chartDrawing" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:odi="http://opendope.org/components" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:lc="http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" xmlns:odq="http://opendope.org/questions" xmlns:wetp="http://schemas.microsoft.com/office/webextensions/taskpanes/2010/11" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid">
<w:tblPr>
    <w:tblStyle w:val="TableGrid"/>
    <w:tblW w:w="0" w:type="auto"/>
    <w:tblLook w:val="04A0"/>
</w:tblPr>
<w:tblGrid>
    <w:gridCol w:w="100"/>
</w:tblGrid>
<w:tr>
    <w:tc>
        <w:tcPr>
            <w:tcW w:w="100" w:type="dxa"/>
        </w:tcPr>
        <w:p/>
    </w:tc>
</w:tr>
<w:sdt>
    <w:sdtPr>
        <w:alias w:val="Repeat"/>
        <w:tag w:val="od:repeat=x1"/>
        <w:id w:val="2058423626"/>
    </w:sdtPr>
    <w:sdtContent>
        <w:tr>
            <w:sdt>
                <w:sdtPr>
                    <w:alias w:val=""/>
                    <w:tag w:val="od:xpath=x0"/>
                    <w:id w:val="947420646"/>
                    <w:dataBinding w:xpath="/invoice[1]/items/item[1]/name" w:storeItemID="{bb8f553d-dc92-4c50-b1cb-06e77bbe149a}"/>
                </w:sdtPr>
                <w:sdtContent>
                    <w:tc>
                        <w:p/>
                    </w:tc>
                </w:sdtContent>
            </w:sdt>
        </w:tr>
    </w:sdtContent>
</w:sdt>

1 Ответ

0 голосов
/ 22 февраля 2019

В JAXB существуют различные объекты Java для элементов управления содержимым, в зависимости от того, переносят ли они содержимое на уровне блоков, на уровне строк, на уровне ячеек или на уровне выполнения.Все эти объекты реализуют интерфейс SdtElement.

Аналогично, существуют различные объекты Java для SdtContent, в зависимости от того, обертывают ли они содержимое уровня блока, уровня строки, уровня ячейки или содержимого уровня выполнения.Все эти объекты расширяют SdtContent.

Вы должны использовать правильные объекты, или, как вы заметили, deepCopy не будет работать.

Я изменил ваш код для использования SdtElement и SdtContent

public class ContentControlFactory {
    ObjectFactory wmlObjectFactory = getWmlObjectFactory();

    public SdtPr createSdtPr(CTDataBinding dataBinding, String tag, String alias) {
        SdtPr sdtPr = createSdtPr(tag, alias);
        sdtPr.setDataBinding(dataBinding);

        return sdtPr;
    }

    public SdtPr createSdtPr(String tag, String alias) {
        Tag t = new Tag();

        SdtPr.Alias a = new SdtPr.Alias();
        a.setVal(alias);
        t.setVal(tag);
        SdtPr sdtPr = wmlObjectFactory.createSdtPr();
        sdtPr.getRPrOrAliasOrLock().add(a);
        sdtPr.setTag(t);

        sdtPr.setId();
        return sdtPr;
    }

    public SdtElement createRepeaterControl(Xpaths.Xpath repeaterXpath, Xpaths.Xpath xpath, Object template) {

        return createSdt(
                createSdtPr("od:repeat=" + repeaterXpath.getId(), "Repeat"),
                createSdtContent(createContentControl(xpath, template))
        );
    }

    public SdtElement createRepeaterControl(Xpaths.Xpath repeaterXpath, Object template) {
        return createSdt(
                createSdtPr("od:repeat=" + repeaterXpath.getId(), "Repeat"),
                createSdtContent(template)
        );
    }

    public SdtElement createContentControl(Xpaths.Xpath xpath, Object template) {
        return createSdt(
                createSdtPr(
                        createDataBinding(xpath.getDataBinding().getXpath(), xpath.getDataBinding().getStoreItemID()),
                        "od:xpath=" + xpath.getId(), ""),
                createSdtContent(template));
    }

    public SdtContent createSdtContent(Object template) {

        System.out.println(template.getClass().getName() );
        SdtContent sdtContent = null; 
        if (template instanceof Tr) {
            sdtContent = wmlObjectFactory.createCTSdtContentRow();
        } else {
            sdtContent = wmlObjectFactory.createSdtContentBlock();

        }

        sdtContent.getContent().add(template);
        return sdtContent;
    }

    public SdtElement createConditionControl(Condition condition, Object template) {
        return createSdt(
                createSdtPr("od:condition=" + condition.getId(), ""),
                createSdtContent(template)
        );
    }

    public SdtElement createSdt(SdtPr sdtPr, SdtContent sdtContent) {
        SdtElement sdtElement = null;

        if (sdtContent instanceof CTSdtContentRow) {
            sdtElement = wmlObjectFactory.createCTSdtRow();
        } else {
            sdtElement = wmlObjectFactory.createSdtBlock();

        }

        sdtElement.setSdtPr(sdtPr);
        sdtElement.setSdtContent(sdtContent);

        return sdtElement;
    }

    public CTDataBinding createDataBinding(String xPath, String storeItemID) {
        CTDataBinding dataBinding = wmlObjectFactory.createCTDataBinding();
        dataBinding.setXpath(xPath);//xPath - это строка с XPath до XML-элемента, связанного с этим Content Control
        dataBinding.setStoreItemID(storeItemID);//storeItemID - это ID корневого XML-элемента, из которого нужно брать данные
        return dataBinding;
    }

}

и исправили случай tr.Вам нужно будет правильно разобраться с другими делами.

...