0
votes

I want to add an existing excel-table to a slide. The excel-file is succefully added to the presentation, using an OleObjectBinaryPart. Now I want to add it to the slide with the following xml code ...

<p:graphicFrame xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
            xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
            xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">
<p:nvGraphicFramePr>
    <p:cNvPr id="3" name="Objekt 2"/>
    <p:cNvGraphicFramePr>
        <a:graphicFrameLocks noChangeAspect="1"/>
    </p:cNvGraphicFramePr>
    <p:nvPr>
        <p:extLst>
            <p:ext uri="{D42A27DB-BD31-4B8C-83A1-F6EECF244321}">
                <p14:modId xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main"
                           val="3436193848"/>
            </p:ext>
        </p:extLst>
    </p:nvPr>
</p:nvGraphicFramePr>
<p:xfrm>
    <a:off x="1524000" y="1433513"/>
    <a:ext cx="6096000" cy="3989387"/>
</p:xfrm>
<a:graphic>
    <a:graphicData uri="http://schemas.openxmlformats.org/presentationml/2006/ole">
        <mc:AlternateContent xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
            <mc:Choice xmlns:v="urn:schemas-microsoft-com:vml" Requires="v">
                <p:oleObj spid="_x0000_s1026" name="Arbeitsblatt" r:id="${OLEObjectRid}" imgW="18573822"
                          imgH="12154029" progId="Excel.Sheet.12">
                    <p:embed/>
                </p:oleObj>
            </mc:Choice>
            <mc:Fallback>
                <p:oleObj name="Arbeitsblatt" r:id="${OLEObjectRid}" imgW="18573822" imgH="12154029"
                          progId="Excel.Sheet.12">
                    <p:embed/>
                    <p:pic>
                        <p:nvPicPr>
                            <p:cNvPr id="0" name=""/>
                            <p:cNvPicPr/>
                            <p:nvPr/>
                        </p:nvPicPr>
                        <p:blipFill>
                            <a:blip r:embed="${ImageId}"/>
                            <a:stretch>
                                <a:fillRect/>
                            </a:stretch>
                        </p:blipFill>
                        <p:spPr>
                            <a:xfrm>
                                <a:off x="1524000" y="1433513"/>
                                <a:ext cx="6096000" cy="3989387"/>
                            </a:xfrm>
                            <a:prstGeom prst="rect">
                                <a:avLst/>
                            </a:prstGeom>
                        </p:spPr>
                    </p:pic>
                </p:oleObj>
            </mc:Fallback>
        </mc:AlternateContent>
    </a:graphicData>
</a:graphic>
</p:graphicFrame>

... using this lines of java-code:

        OleObjectBinaryPart olePart;
    Relationship relOleObject = null;
    BinaryPartAbstractImage imagePart = null;

    // OleObject
    try {
        olePart = new OleObjectBinaryPart(new PartName("/ppt/embeddings/Microsoft_Office_Excel_Worksheet1.xlsx"));
        // get the excel-file
        olePart.setBinaryData(getXlsxAsInputStream());
        relOleObject = presentationMLPackage.getMainPresentationPart().addTargetPart(olePart);
    } catch (InvalidFormatException e) {
        log.error("Could not create OlePart. ", e);
        e.printStackTrace();
    }

    // Preview image
    InputStream inputStream = this.getClass().getResourceAsStream("/images/beispielbild_gross1.jpg");
    byte[] bytes;
    try {
        bytes = IOUtils.toByteArray(inputStream);
        imagePart = BinaryPartAbstractImage.createImagePart(presentationMLPackage, slidePart, bytes);
    } catch (IOException e) {
        log.error("Could not convert image to byte[]. ", e);
    } catch (Exception e) {
        log.error("Could not add image to presentation. ", e);
    }

    // The image the user sees, that they click on to open the object
    Relationship relImage = null;
    try {
        relImage = presentationMLPackage.getMainPresentationPart().addTargetPart(imagePart);
    } catch (InvalidFormatException e) {
        e.printStackTrace();
    }

    // get content of xml-file
    String ml = readFile("/xml/oleObject.xml");

    java.util.HashMap<String, String> mappings = new java.util.HashMap<String, String>();
    mappings.put("ImageId", relImage.getId());
    mappings.put("OLEObjectRid", relOleObject.getId());

    try {
        CTGraphicalObjectFrame sample = (CTGraphicalObjectFrame) XmlUtils.unmarshallFromTemplate(ml, mappings, Context.jcPML, CTGraphicalObjectFrame.class);
        slidePart.getContents().getCSld().getSpTree().getSpOrGrpSpOrGraphicFrame().add(sample);
    } catch (JAXBException e) {
        log.error("Could not add content to slide.", e);
    }

But unmarshalling the xml-Code (the substitution works correctly) I get the following error:

javax.xml.bind.UnmarshalException: unexpected element (uri:"http://schemas.openxmlformats.org/presentationml/2006/main", local:"graphicFrame"). Expected elements are [... lots of elements but not graphicFrame ...]

So which element do I have to use instead of graphicFrame? Or is my problem somewhere else?

UPDATE: Adding CTGraphicalObjectFrame.class to the unmarshal function fixed the problem. But I can not open the finished file, MS Office says it is broken. Any hints?

1
You have xmlns:p="schemas.openxmlformats.org/drawingml/2006/main". Don't you mean presentationml?JasonPlutext
You're right. I changed it, but the error message is almost the same (see above).spilymp

1 Answers

0
votes

In this case you need to give JAXB a hint:

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

import org.docx4j.XmlUtils;
import org.pptx4j.jaxb.Context;
import org.pptx4j.pml.CTGraphicalObjectFrame;

public class FileToPML {
public static void main(String[] args) throws Exception {

    String inputfilepath = System.getProperty("user.dir") + "/pml.xml";
    java.io.FileInputStream fin = new java.io.FileInputStream(inputfilepath);

    // Create Unmarshaller
    JAXBContext jc = Context.jcPML;
    Unmarshaller u = jc.createUnmarshaller();
    u.setEventHandler(new org.docx4j.jaxb.JaxbValidationEventHandler());

    // Unmarshall, giving JAXB a hint
    Object o = u.unmarshal(new javax.xml.transform.stream.StreamSource(fin), 
            CTGraphicalObjectFrame.class);

    // Prove it worked
    System.out.println(o.getClass().getName());
    System.out.println(XmlUtils.marshaltoString(o, Context.jcPML));

}

}