Search code examples
javaopenxmldocxdocx4j

Save WordprocessingMLPackage to ByteArrayInputStream


How can I save a org.docx4j.openpackaging.packages.WordprocessingMLPackage instance into ByteArrayInputStream, then It can be downloaded from server.

Thanks.


Solution

  • You cannot save to a ByteArrayInputStream ... ever. A ByteArrayInputStream is an InputStream and you don't / can't write to an InputStream.

    However you can write something to a ByteArrayOutputStream, get the byte array, and create a ByteArrayInputStream wrapper for the array.

    (I'm assuming that there is a way to save one of those instances to an OutputStream or Writer ...)


    Well, my assumption was wrong, and WordprocessingMLPackage's only save method saves to a File. (I guess someone didn't get the memo on how to design flexible I/O apis ...)

    But the source code ( here ) offers some clues on how you could implement it yourself. The method is as follows:

    public void save(java.io.File docxFile) throws Docx4JException {
    
        if (docxFile.getName().endsWith(".xml")) {
    
            // Create a org.docx4j.wml.Package object
            FlatOpcXmlCreator worker = new FlatOpcXmlCreator(this);
            org.docx4j.xmlPackage.Package pkg = worker.get();
    
            // Now marshall it
            JAXBContext jc = Context.jcXmlPackage;
            try {
                Marshaller marshaller=jc.createMarshaller();
    
                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
                                                       Boolean.TRUE);
                NamespacePrefixMapperUtils.setProperty(marshaller, 
                        NamespacePrefixMapperUtils.getPrefixMapper());          
    
                marshaller.marshal(pkg, new FileOutputStream(docxFile));
            } catch (Exception e) {
                throw new Docx4JException("Error saving Flat OPC XML", e);
            }   
            return;
        }
    
        SaveToZipFile saver = new SaveToZipFile(this); 
        saver.save(docxFile);
    }
    

    It looks like you should be able to copy this code in a helper class, and tweak it to save to a OutputStream rather than (specifically) a FileOutputStream. Note that the SaveToZipFile class has alternative save methods that write to an OutputStream.