Duplicate slides / Re-import pptx files from pptx-automizer's output
Hello guys,
Having some issues with updating the content of a slide and getting back the new elements from the resulting presentation.
What we use to update the slides is something like below
`
slides.forEach((slide) => {
const slideUpdates = updatesBySlide.get(slide.number);
if (slideUpdates) {
pres.addSlide(
`${fileName}-template`,
slide.number,
(slideObj: ISlide) => {
slideUpdates.forEach((update) => {
const shape = slide.elements.find(
(element) =>
element.name === update.name &&
Math.abs(element.position.x - update.emuPosition.x) < 1000 &&
Math.abs(element.position.y - update.emuPosition.y) < 1000 &&
Math.abs(element.position.cx - update.emuPosition.cx) <
1000 &&
Math.abs(element.position.cy - update.emuPosition.cy) < 1000
);
if (shape && shape.hasTextBody) {
slideObj.modifyElement(update.name, [
ModifyTextHelper.setText(update.textContent.join("\n")),
]);
}
});
}
);
} else {
// If no updates for this slide, still need to add it to maintain presentation structure
pres.addSlide(`${fileName}-template`, slide.number);
}
});
`
This seems to be working great and creating the correct pptx file when saving it like below
const outputPath = path.join(outputDir, fileName); await pres.write(fileName);
But when we try to pull out all the slides from the pptx with something like below:
`
const pres = automizer.load(fileName, `${fileName}-template`);
const presInfo = await pres.getInfo();
const slides = presInfo
.slidesByTemplate(`${fileName}-template`)
.map((slide) => {
const slideNumber = slide.number;
return {
number: slide.number,
name: slide.info.name,
shapes: slide.elements
.filter(
(shape) =>
shape.hasTextBody === true && shape.getText().length !== 0
)
.map((shape) => {
const text = shape.getText();
return {
name: shape.name,
type: shape.type,
text: text,
position: {
x: shape.position.x,
y: shape.position.y,
cx: shape.position.cx,
cy: shape.position.cy,
},
};
}),
};
});
`
What I find is that the below has double the number of slides than what I expect which I think partially makes sense just that I was expecting for the old slides to not be kept especially as we use removeExistingSlides: true
presInfo.slidesByTemplate(${fileName}-template)
Any idea what am I misunderstanding?
Hi @Idriosiris ! There is no misunderstanding, the slides are only removed from the slides list, but not at all removed from the archive.
I did some testing to re-use outputted files from pptx-automizer, but didn't succeed, too. You will need to manually save a file in PowerPoint once to be able to automizer.load it again, I'm so sorry! It's a dark secret you have discovered.
You could try and set cleanup: true flag besides removeExistingSlides: true, but I'm not sure if this really helps.
It's basically because getCreationIds() at xml-template-helper.ts finds the existing slides by their appearance in ppt/_rels/presentation.xml.rels, which isn't cleaned up.
So we're saying that there is currently no way of modifying a pptx which was already edited via Automizer unless we open it in powerpoint and give it a manual save.
Are there any active hypothesis on how this could be fixed? Asking as this is a use-case that would be highly valuable for me and could put some time to getting it fixed.
I did look at this very very briefly a while ago. It can definitely be done but it will require a couple of days of effort, I think.
I'll go deeper into this! Thanks, @Idriosiris , I will figure out what is required exactly.
I'm sorry for the late response, @Idriosiris.
I was testing a little with modifying an already modified chart, which is now working with a little tweaking - unexpectedly. :)
I've created a branch and placed a ToDo at src/helper/xml-template-helper.ts.
The thing regarding your situation is: The slide list from pres.getInfo() is based on uncleaned relations that contain non-visible slides, too.
It should be either:
a.) remove unused slides on generation (my preferred)
b.) use slides list from 'p:sldIdLst' in ppt/presentation.xml
I'm happy for comments!
You can run yarn dev on the new branch for a happy dev experience!
Hi mates, are there any updates from that?
Seems when enabling cleanup: true besides removeExistingSlides: true, we still cannot reimport to automizer anymore.
Hi @duchm1606 ! Is it possible to provide a generated pptx for testing? I was playing around, but all my test files can be re-imported...
Hi @duchm1606 ! Is it possible to provide a generated pptx for testing? I was playing around, but all my test files can be re-imported...
@singerla https://wiki.documentfoundation.org/images/4/47/Extlst-test.pptx
Fyi maybe the file has lost the slide1 so it throw an error when loading again the file. Using buffer
const jszip = await automizer.getJSZip();
const modifiedBuffer = Buffer.from(await jszip.generateAsync({ type: 'nodebuffer' }));
Ok, I'm testing this:
- load the Extlst-test.pptx as root and add some slides to it.
- save as Extlst-test.mod.pptx
- create a new instance and load Extlst-test.mod.pptx, add some slides to it
- save as Extlst-test.mod.mod.pptx => Opens with PowerPoint complaining repair-message.
The slide you have sent contains a SmartArt, which is supported only for a few weeks now, I did not test this a lot. Might be related to this special SmartArt content?
I could not find an obvious problem in the mod.mod, any idea on how to target this?
Can we try with a version removing this smart art first?
Have tried to modify text in the first slide, and export to buffer with two flags on. Right after that when I import back this as the template to automizer instance, I get an error that cannot find information of slide1. Checking the template info I see that the slide number start from 2.
Guess that when we cleanup the root template using removeExistingSlides: true and cleanup: true, the removing root's slide happen after the adding operations, making the new added ones start from a slide number other than 1