singerla / pptx-automizer

A template based pptx generator for Node.js
MIT License
68 stars 12 forks source link

Tip: How To Loop Through Slides and/or Programatically Replace Text #72

Open vertex-admin opened 1 year ago

vertex-admin commented 1 year ago

It took me hours to figure this out so thought I'd share a quick workaround on how to: i) loop through all the slides in a presentation ii) replace all instances of the text you want to replace, without needed to know/hardcode the selector names

This won't work for text in tables though, if anyone has a tip on how to do that, I'd be happy to try.

   let variableData = [{variable: "First Name", value: "John"}, {variable: "Last Name", value: "Doe"}]
   let textReplacements = [];
   let templateName = 'test';

    variableData.forEach(async variable => {
        textReplacements.push({
            replace: variable.variable,
            by: {
                text: variable.value,
            },
        });
    });

    // Load Pptx Automizer
    const automizer = new Automizer({
        templateDir: templateDir,
        outputDir: outputDir,
        removeExistingSlides: true,
    });

    let pres = automizer.loadRoot(rootTemplate).load(extraTemplate, templateName);

    // Count the total number of slides
    const creationIds = await pres.setCreationIds();
    let totalSlides = 0;

    creationIds.forEach((template) => {
        totalSlides += template.slides.length;
    });

    console.log(`Processing ${totalSlides} slides!`);

    // Loop through all the slides
    for (let i = 1; i <= totalSlides; i++) {
        pres.addSlide(templateName, i, async slide => {
            let placeholders = await slide.getAllTextElementIds();    

            // Replace text for each placeholder programatically
            placeholders.forEach(async placeholder => {
                slide.modifyElement(
                    placeholder,
                    modify.replaceText(textReplacements),
                );
            });
        });
    }

    // Write the output file
    pres.write('Output.pptx').then((summary) => {
        console.log(summary);
    });
singerla commented 1 year ago

Great! Thanks a lot for sharing! :smiley:

You can make use of the new pres.getInfo() that came yesterday with v0.4.1 to make the code even shorter:

    // ...

    let pres = automizer.loadRoot(rootTemplate).load(extraTemplate, templateName);

    // getInfo() is a tiny wrapper around setCreationIds():
    const presInfo = await pres.getInfo();
    // Count the total number of slides
    const totalSlides = presInfo.slidesByTemplate(templateName).length;

    console.log(`Processing ${totalSlides} slides!`);

    // Loop through all the slides
    // ...

Best regards and keep on sharing!