Stefan
Stefan

Reputation: 322

pass values from java variables to microsoft word (doc and docx) variables

How can i replace a microsoft word document variable value with a value from a java variable ? I have a .doc or .docx file template in which i have defined some variables.

When user click on download button from my app the .doc or .docx variables must get the value from java variables.

Upvotes: 0

Views: 3510

Answers (2)

Alexander Davliatov
Alexander Davliatov

Reputation: 863

I use docx4j for that purpose:

        String inputfilepath = "binding-simple1.docx";
        String outputfilepath = "OUT_VariableReplace.docx";

        WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage
                .load(new java.io.File(inputfilepath));
        MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();

        HashMap<String, String> mappings = new HashMap<String, String>();
        mappings.put("subjectId", "E000001");

        // Approach 1 (from 3.0.0; faster if you haven't yet caused unmarshalling to occur):

        documentPart.variableReplace(mappings);
        Docx4J.save(wordMLPackage, new File(outputfilepath));

Variable param as the following: ${subjectId}

Upvotes: 1

Cyril Duchon-Doris
Cyril Duchon-Doris

Reputation: 13929

I am responsible for a Play! intranet that generates word documents using templates that have a .docx extension. To achieve this, we have the following inheritance tree : Document > Word > [someDocument]

The abstract class Word handles replacing variables in Word documents

public abstract class Word extends Document {
    public static JAXBContext context = org.docx4j.jaxb.Context.jc;

    public Word(String inputfilepath){
        super(inputfilepath);
    }

    public String generer(String outputfilepath) throws Exception {

        //String inputfilepath = System.getProperty("user.dir")+"/app/doc/adhesionTemplate.docx";

        //String outputfilepath = System.getProperty("user.dir")+ "/test-out.docx";

        // Open a document from the file system
        // 1. Load the Package
        WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new java.io.File(inputfilepath));

        // 2. Fetch the document part
        MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();

        org.docx4j.wml.Document wmlDocumentEl = (org.docx4j.wml.Document) documentPart.getJaxbElement();

        // xml --> string
        String xml = XmlUtils.marshaltoString(wmlDocumentEl, true);

        //Change the variables using an abstract function getMapping()
        HashMap<String, String> mappings = getMapping();

        Object obj = XmlUtils.unmarshallFromTemplate(xml, mappings);

        // change JaxbElement
        documentPart.setJaxbElement((org.docx4j.wml.Document) obj);

        //Footers : 
        List<SectionWrapper> wrappers = wordMLPackage.getDocumentModel().getSections();
        for (SectionWrapper sw : wrappers) {
            FooterPart footer = sw.getHeaderFooterPolicy().getDefaultFooter();
            if (footer != null) {
                Ftr footerDoc = footer.getJaxbElement();
                String footerXml = XmlUtils.marshaltoString(footerDoc, true);
                Object footerObj = XmlUtils.unmarshallFromTemplate(footerXml, mappings);
                footer.setJaxbElement( (Ftr) footerObj);
            }
        }

        // Save it
        SaveToZipFile saver = new SaveToZipFile(wordMLPackage);
        saver.save(outputfilepath);
        Console.commande("sudo chmod 660 \"" + outputfilepath + "\"");

        System.out.println("Saved output to:" + outputfilepath);

        return outputfilepath;

    }

Then, we have classes that inherit from this Word abstract class:

public class FAC extends Word {

    public FAC() {
        super(System.getProperty("user.dir") + "/templates/Facture.docx");
    }

    @Override
    public HashMap<String, String> getMapping() {

        //Preparing variables
        int price = blablabla;

        HashMap<String, String> map = new HashMap<String, String>();

        map.put("FACDate", Utils.dateConvert(new Date()));
        map.put("somePrice", String.valueOf(price));


        return map;
    }
}

Note : the "Document" superclass has nothing special, just a variable "inputFilePath", and the abstract method getMapping()

Hope this help, either you or future viewers like me :P

Upvotes: 0

Related Questions