Page 1 of 1

duplicate an existing slide in the middle of a pptx

PostPosted: Mon Jun 13, 2011 8:37 am
by sudr
I need to populate data for a table on a powerpoint slide that is in the middle of a slide deck. And I need to implement paging when the number of rows exceeds what can be accommodated on a single slide.

So, the approach I'd like to take is to duplicate the slide with the table on it and populate the second page of data and so on. How can I use pptx4j to duplicate a slide and insert it right after the slide that is being duplicated?

Thanks in advance for the help.

Re: duplicate an existing slide in the middle of a pptx

PostPosted: Mon Jun 13, 2011 10:45 am
by jason
Steps:

- Find your existing slide
- get its JAXB content
- clone it (use deepCopy method in XmlUtils)
- create a new slide (see createSlidePart in PresentationMLPackage
- set its content equal to the clone
- add the new slide to the presentation (you'll need to alter the createSlidePart and/or addSlideIdListEntry method, so your slide is slotted in to MainPresentationPart' at the appropriate place).

When you get it working, perhaps you could post your code for the benefit of others?

cheers .. Jason

Re: duplicate an existing slide in the middle of a pptx

PostPosted: Fri Jun 17, 2011 1:57 am
by sudr
"- add the new slide to the presentation (you'll need to alter the createSlidePart and/or addSlideIdListEntry method, so your slide is slotted in to MainPresentationPart' at the appropriate place)."

Can you elaborate on what changes I need to make in createSlidePart and/or addSlideIdListEntry. Since I need to insert the new slide in the middle of the an existing powerpoint file, it sounds like I need to iterate through all the slides coming after the insertion point and bump their part names by 1. How will this work with slideLayout's for these slides and other parts related this these slides that get bumped down.

Also, in your pseudo code, does cloning the "clone it (use deepCopy method in XmlUtils)" step account for the slideLayout and other elements on the slide being cloned like notes etc. Or do I need to clone these other parts as well and set them on the new slide.

Re: duplicate an existing slide in the middle of a pptx

PostPosted: Fri Jun 17, 2011 2:18 am
by jason
- add the new slide to the presentation (you'll need to alter the createSlidePart and/or addSlideIdListEntry method, so your slide is slotted in to MainPresentationPart' at the appropriate place)."

Can you elaborate on what changes I need to make in createSlidePart and/or addSlideIdListEntry. Since I need to insert the new slide in the middle of the an existing powerpoint file, it sounds like I need to iterate through all the slides coming after the insertion point and bump their part names by 1. How will this work with slideLayout's for these slides and other parts related this these slides that get bumped down.


I don't think you'll need to bump their part names.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
        public Presentation.SldIdLst.SldId addSlideIdListEntry(SlidePart slidePart)
                throws InvalidFormatException {

                Relationship rel = this.addTargetPart(slidePart);
               
                Presentation.SldIdLst.SldId entry = Context.getpmlObjectFactory().createPresentationSldIdLstSldId();
               
                entry.setId( this.getSlideId() );
                entry.setRid(rel.getId());
               
                this.jaxbElement.getSldIdLst().getSldId().add(entry);
               
                return entry;
               
        }
 
Parsed in 0.016 seconds, using GeSHi 1.0.8.4


this.jaxbElement.getSldIdLst().getSldId() is a list; just add the entry at your desired position.

Also, in your pseudo code, does cloning the "clone it (use deepCopy method in XmlUtils)" step account for the slideLayout and other elements on the slide being cloned like notes etc. Or do I need to clone these other parts as well and set them on the new slide.


Any rels required by the slide will need to be added (using addTargetPart method). You won't necessarily need to clone the part; slides can point to the same part.

Suggest you run your sample pptx through the PartsList sample to see the rels hierarchy.

hope this helps .. Jason

Re: duplicate an existing slide in the middle of a pptx

PostPosted: Fri Jun 17, 2011 2:33 am
by sudr
- add the new slide to the presentation (you'll need to alter the createSlidePart and/or addSlideIdListEntry method, so your slide is slotted in to MainPresentationPart' at the appropriate place).


Is there a specific method that I need to call to add the new slide to the presentation. Shouldn't the earlier call to createSlidePart already add the slide to the presentation?

Re: duplicate an existing slide in the middle of a pptx

PostPosted: Fri Jun 17, 2011 3:57 am
by sudr
Also, I get the following stacktrace when I invoke
Code: Select all
Sld jaxbElement = slidePart.getJaxbElement();
Sld deepCopy = XmlUtils.deepCopy(jaxbElement);


Code: Select all
2011-06-16 10:43:07 ERROR Unexpected exception.
java.lang.IllegalArgumentException: javax.xml.bind.MarshalException
- with linked exception:
[javax.xml.bind.JAXBException: org.pptx4j.pml.Sld is not known to this context]
   at org.docx4j.XmlUtils.deepCopy(XmlUtils.java:621)
   at org.docx4j.XmlUtils.deepCopy(XmlUtils.java:570)


Looks like this may be the same issue as in:
pptx-java-f14/ctgraphicframe-problem-when-creating-a-chart-t683.html

I've been using version 2.6.0. I will switch to the latest trunk version and see if this issue is fixed.

Re: duplicate an existing slide in the middle of a pptx

PostPosted: Fri Jun 17, 2011 5:37 am
by sudr
I figured out that I need to pass in the JAXBContext for the slidePart, else it defaults to the default JAXBContext which does not have the "org.pptx4j.pml" package.

Sld deepCopy = XmlUtils.deepCopy(jaxbElement, slidePart.getJAXBContext());

Re: duplicate an existing slide in the middle of a pptx

PostPosted: Fri Jun 17, 2011 8:54 am
by sudr
this.jaxbElement.getSldIdLst().getSldId() is a list; just add the entry at your desired position.


Just so that I am understanding this right, currently the MainPresentationPart.addSlideIdListEntry(SlidePart) does not take into account that the partName property of the slidePart parameter indicates where in the powerpoint the slide should be created. It will aways add it to the end of the powerpoint.

Instead for my purposes, I need to modify the addSlideIdListEntry method to look at the partName attribute of the slidePart and insert it into the list at the right sequential position, correct?

Re: duplicate an existing slide in the middle of a pptx

PostPosted: Fri Jun 17, 2011 9:50 am
by jason
sudr wrote:take into account that the partName property of the slidePart


The part name is arbitrary. It could be "/ppt/slides/monkeys.xml" for all it matters.

AFAIK, adding in the right sequential position is all that matters.

Re: duplicate an existing slide in the middle of a pptx

PostPosted: Thu Jan 03, 2013 5:02 pm
by gopalkalasa
Hi Sudr,

I am also in the same situation. If you found out any solution can you please paste the code. It will be much helpful.




Thanks in advance
Gopal

Re: duplicate an existing slide in the middle of a pptx

PostPosted: Sun Oct 04, 2015 3:04 am
by Vertinog
Code: Select all
JAXBContext releaseContext = releaseSlide.getSlidePart().getJAXBContext();
            SlidePart outputSlide = new SlidePart();
            Sld outputSld = XmlUtils.deepCopy(releaseSlide.getSlidePart().getContents(), releaseContext);
            outputSlide.setContents(outputSld);
            outputSlide.setPartShortcut(releaseSlide.getSlidePart().getSlideLayoutPart());
            outputSlide.setPartShortcut(releaseSlide.getSlidePart().getCommentsPart());
            outputSlide.setPartShortcut(releaseSlide.getSlidePart().getNotesSlidePart());
            outputSlide.setPartShortcut(releaseSlide.getSlidePart().getRelationshipsPart());


I am doing the above and still getting the same error as the original poster. I add the outputSlide to the MainPresentationPart after doing this deepCopy. Has anyone figured out how to do this?

Re: duplicate an existing slide in the middle of a pptx

PostPosted: Sun Oct 04, 2015 5:51 pm
by jason
Vertinog wrote:I am doing the above and still getting the same error as the original poster.


What error is that? Its not clear whether your problem is that your new slide is missing, or to do with its content (eg too much content)

Re: duplicate an existing slide in the middle of a pptx

PostPosted: Mon Oct 05, 2015 11:40 am
by Vertinog
jason wrote:What error is that? Its not clear whether your problem is that your new slide is missing, or to do with its content (eg too much content)



Hi Jason,

I made a bad assumption that the thread I was posting in had an image at the top stating that the presentation was corrupted when trying to open the new one. I was looking at many threads that day and got them jumbled up.

As for my issue I am assuming it is something to do with the relationship parts or another linkage that I am missing. Also based on other threads I have read I see a lot of RTFM going on around here so I will instead just read up on the document format and figure out the issue I am seeing.

Re: duplicate an existing slide in the middle of a pptx

PostPosted: Mon Oct 05, 2015 6:41 pm
by jason
OK, well the bit missing in the code you posted is invoking one of the addSlide methods in MainPresentationPart.

If you do that, it should "just work".

If you don't do that (or manually invoke addTargetPart), then your new part is never added to the pptx, hence a possible source of the error you mention.

Re: duplicate an existing slide in the middle of a pptx

PostPosted: Mon Oct 05, 2015 10:15 pm
by Vertinog
Ah well I do add it using the mainpresentaionpart later on and it creates the presentation just fine. When loading the slide show in PowerPoint it complains about corrupt slides and those will be loaded as blank.

When I add the slide I am cloning it works fine, if I do a direct clone and then add it gives the above corrupt error.

*Edit*

I opened the presentation up using 7zip and took a look at the contents. It seems like I may be missing the relationship information for the slide I created and its notes, slidelayout and theme override files. I will continue looking into this and see if I can resolve the relationship information. It looks like the file is being generated without the _rels directory in the slides folder.

*Edit 2*

Stepping through the code in a debugger I am seeing that the relationships is null for the newly copied slide as well as the contentLengthAsLoaded is -1. So it does look like the relationships could be the issue. I will keep looking into it to see how to correct this.

*Edit 3*

It is the relationships being null that is the issue. I now need to figure out how to create those relationships correctly. Anyways I believe I am on my way to fixing my issue. Thanks.

Re: duplicate an existing slide in the middle of a pptx

PostPosted: Tue Oct 06, 2015 9:01 am
by jason
Does the following work for you?

https://github.com/plutext/docx4j/blob/ ... World.java

You'll see it also does:

slidePart.addTargetPart(layoutPart);

If it has problems loading the slide show in PowerPoint, which version of Powerpoint?

Re: duplicate an existing slide in the middle of a pptx

PostPosted: Tue Oct 06, 2015 1:18 pm
by Vertinog
Hi Jason,

So I did end up using that example as well as an example of how to correctly remove slides. In the end I wasn't removing slides correctly from my presentation, correctly copying the table cells I was trying to use and correctly adding the target layout part as you mentioned. Once I did all of the above it started working perfectly.

Thank you for your help!