Concatenating several
entire pptx
Concatenating parts of
several pptx
MergePPtx is a utility for concatenating pptx presentations together.
It can be used to "re-brand" presentations to have the same look and feel (“theme”) as the first one.
Alternatively (since v3.2.0.3), you can keep each presentation’s existing theme.
In principle, it could be used to remove slides from a presentation, but there are more efficient ways of doing that.
A SlideRange represents the slides in a source pptx to be merged.
The simplest constructor says to use the entire presentation (ie all the slides):
public
SlideRange(PresentationMLPackage pmlPkg) throws
MergePptxException
Other constructors are discussed below.
To do this:
· construct a PresentationBuilder object
·
create a SlideRange for each
pptx, and add it, with
builder.addSlideRange(sr);
·
get the resulting PresentationMLPackage
using
builder.getResult();
The result is a new PresentationMLPackage containing the contents of the source decks.
For example:
String[]
deck = {"deck1.pptx" , "deck2.pptx"};
PresentationBuilder
builder = new PresentationBuilder();
for (int i=0 ;
i< deck.length; i++) {
// Create a SlideRange representing the slides
in this pptx
SlideRange sr = new
SlideRange(
(PresentationMLPackage)OpcPackage.load(
new File(DIR_IN +
deck[i])));
sr.setName(i+ "
" + deck[i]); //
PkgIdentifier for ListeningBean
// Add the slide range to the output
builder.addSlideRange(sr);
}
PresentationMLPackage
result = builder.getResult();
If you want to use a particular pptx morethan once, you should use clones for
each of the subsequent times.
The samples directory contains an example called MergeWholePresentations.
Note: versions earlier than v3.2.0 suggested: List<PresentationMLPackage>
pmlPkgs = … PresentationMLPackage result = PresentationBuilder.merge(pmlPkgs); however, that requires each input pptx to be in memory at the same time. Accordingly, that approach is now deprecated. |
If you wish to use only a certain slides, you use the SlideRange constructor:
/**
* @param pmlPkg
* @param slideNumber 0-based
* @throws
MergePptxException
*/
public
SlideRange(PresentationMLPackage pmlPkg,
int[] slideNumber) throws
MergePptxException
For example:
PresentationBuilder builder = new
PresentationBuilder();
int[] range1
= {2,4,6,8};
builder.addSlideRange( new SlideRange(
(PresentationMLPackage)OpcPackage.load(new File(DIR_IN + "microsoft1.pptx")),
range1)
);
int[] range2 = {1,3,5};
builder.addSlideRange( new SlideRange(
(PresentationMLPackage)OpcPackage.load(new File(DIR_IN + "oracle.pptx")),
range2)
);
PresentationMLPackage
result = builder.getResult();
If you want to use a particular pptx in morethan one SlideRange, you should use clones for each of the subsequent times.
The result is a new PresentationMLPackage containing the contents of the source decks.
The samples directory contains an example called MergeListedSlides.
/**
* Specify the source package,
from "start" (0-based index) to
the end of the document
* @param wordmlPkg
* @param start
* @throws
MergePptxException
*/
public SlideRange(PresentationMLPackage pmlPkg, int start) throws MergePptxException
/**
* Specify the source package,
from "start" (0-based index) and
include "count"
* slides
*
* @param wordmlPkg
* @param start
* @param count
* @throws
MergePptxException
*/
public
SlideRange(PresentationMLPackage pmlPkg, int start, int count) throws
MergePptxException
The easiest way to delete slides is to use:
public SlideRange(PresentationMLPackage pmlPkg, int[] slideNumber)
putting all the slides you want to keep in the array.
(since v3.2.0.3)
In a pptx, each slide has a slide layout part.
Each slide layout:
· has a name
· uses a slide master.
And each slide master is linked to a theme.
· A theme has a name, but a slide master doesn’t.
· Generally, there is a 1:1 relationship between theme and slide master.
So we have this sort of structure:
(Note: a slide layout can also specify a themeOverride.)
In PowerPoint, you can see this if you click View > Slide Master. For example:
|
At the top of the hierarchy is the theme/slidemaster. The name of the theme is given by the mouseover. Under each theme/slidemaster, are the associated slide layouts. You can mouseover these to see which slides uses a given layout. |
By default, MergePptx will use the theme(s) defined in the first presentation. So a slide in a subsequent presentation which uses layout “Title and Content” defined in the first presentation, will take on that appearance.
If a slide uses a layout name not previously encountered (likely a custom layout name), that layout will be added, and associated with an existing theme.
You can use ThemeTreatment.RESPECT to have the theme names act as a namespace:
PresentationBuilder builder = new
PresentationBuilder();
builder.setThemeTreatment(ThemeTreatment.RESPECT);
In this case, a slide in a subsequent presentation which uses layout “Title and Content” defined in the first presentation, will only take on the appearance of the earlier presentation if they use a theme with the same name. Otherwise, the theme/master and layout will be imported.
The screenshot above is an example of the Slide Master view for a presentation generated using ThemeTreatment.RESPECT.
Note that only the name of the theme matters. In a subsequent release, we may support renaming themes which have same name but different content.
If you want to see how your input is being processed, set logger:
<logger name="com.plutext.merge.pptx.ThemeTreatment">
<level value="info"/>
</logger>
(and set other loggers to warn or error). This will produce output like:
ThemeTreatment
.appendSlideRange line 515 - /ppt/slides/p3_slide1.xml
ThemeTreatment .handleLayout
line 582 - Uses layout OPN_02_2003:Blank
ThemeTreatment .handleLayout
line 588 - .. which we need to add
ThemeTreatment .importLayout
line 698 - Importing master /ppt/slideMasters/slideMaster1.xml
ThemeTreatment
.appendSlideRange line 515 - /ppt/slides/p3_slide2.xml
ThemeTreatment .handleLayout
line 582 - Uses layout OPN_02_2003:Title Slide
ThemeTreatment .handleLayout
line 588 - .. which we need to add
ThemeTreatment
.appendSlideRange line 515 - /ppt/slides/p3_slide3.xml
ThemeTreatment .handleLayout
line 582 - Uses layout OPN_02_2003:Title and Content
ThemeTreatment .handleLayout
line 588 - .. which we need to add
ThemeTreatment
.appendSlideRange line 515 - /ppt/slides/p3_slide4.xml
ThemeTreatment .handleLayout
line 582 - Uses layout OPN_02_2003:Title and Content
ThemeTreatment .handleLayout line 591 - .. which is already present (in /ppt/slideLayouts/slideLayout211.xml
Since merging presentations can take some time (depending on the number and complexity of the presentations), the possibility exists of performing the merge in the background, and receiving notification when the job is complete.
The MergeWholePresentations sample contains an example of usage.
As per that example, you need to:
This is done as follows:
// Creation of message bus
MBassador<Docx4jEvent> bus = new
MBassador<Docx4jEvent>(
BusConfiguration.Default());
// tell Docx4jEvent to use your message bus for
notifications
Docx4jEvent.setEventNotifier(bus);
// Define and register/subscribe a listener
ListeningBean listener = new
ListeningBean();
bus.subscribe(listener);
The samples package contains an example
ListeningBean. Note the @Handler
annotation.
Docx4j’s approach to event monitoring relies on
the MBassador
library; see further https://github.com/bennidi/mbassador
For another example of monitoring events (docx
load, save), please see https://github.com/plutext/docx4j/blob/master/src/samples/docx4j/org/docx4j/samples/EventMonitoringDemo.java