Search code examples
javapowerpointdocx4j

How to replace text in Powerpoint file with Java


I have a requirement where I need to replace some text in a Powerpoint File at runtime. (Powerpoint file is being used as a template with some placeholders/tokes e.g. {{USER_NAME}}) I have tried using POI but with no luck. I referred to the other links on the forum and started with 'docx4j' but am not able to go beyond a point and the documentation is not very clear (at least for me). Here is what I have done so far: Got the PPTX loaded to 'PresentationMLPackage' Got the 'MainPresentationPart' and the slides (Using mainPresentationPart.getSlide(n);)

But I am not sure of the next steps from here (or if this is the right approach in the first place).

Any suggestions will be greatly appreciated.

Thanks a Lot, -Vini


Solution

  • SlidePart extends JaxbPmlPart<Sld>
    JaxbPmlPart<E> extends JaxbXmlPartXPathAware<E>
    JaxbXmlPartXPathAware<E> extends JaxbXmlPart<E>
    

    JaxbXmlPart contains:

    /**
     * unmarshallFromTemplate.  Where jaxbElement has not been
     * unmarshalled yet, this is more efficient (3 times
     * faster, in some testing) than calling
     * XmlUtils.marshaltoString directly, since it avoids
     * some JAXB processing.  
     * 
     * @param mappings
     * @throws JAXBException
     * @throws Docx4JException
     * 
     * @since 3.0.0
     */
    public void variableReplace(java.util.HashMap<String, String> mappings) throws JAXBException, Docx4JException {
    
        // Get the contents as a string
        String wmlTemplateString = null;
        if (jaxbElement==null) {
    
            PartStore partStore = this.getPackage().getSourcePartStore();
            String name = this.getPartName().getName();
            InputStream is = partStore.loadPart( 
                    name.substring(1));
            if (is==null) {
                log.warn(name + " missing from part store");
                throw new Docx4JException(name + " missing from part store");
            } else {
                log.info("Lazily unmarshalling " + name);
    
                // This seems to be about 5% faster than the Scanner approach
                try {
                    wmlTemplateString = IOUtils.toString(is, "UTF-8");
                } catch (IOException e) {
                    throw new Docx4JException(e.getMessage(), e);
                }
            }
    
        } else {
    
            wmlTemplateString = XmlUtils.marshaltoString(jaxbElement, true, false, jc);
    
        }
    
        // Do the replacement
        jaxbElement = (E)XmlUtils.unwrap(
                            XmlUtils.unmarshallFromTemplate(wmlTemplateString, mappings, jc));
    
    }
    

    So once you have the slide part, you can invoke variableReplace on it. You'll need your variables to be in the format expected by XmlUtils.unmarshallFromTemplate