How to merge two word documents which are saved with .docx to a third file? How to merge two word documents which are saved with .docx to a third file? apache apache

How to merge two word documents which are saved with .docx to a third file?


I've developed the next class:

import java.io.InputStream;import java.io.OutputStream;import java.util.ArrayList;import java.util.List;import org.apache.poi.openxml4j.opc.OPCPackage;import org.apache.poi.xwpf.usermodel.XWPFDocument;import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;public class WordMerge {    private final OutputStream result;    private final List<InputStream> inputs;    private XWPFDocument first;    public WordMerge(OutputStream result) {        this.result = result;        inputs = new ArrayList<>();    }    public void add(InputStream stream) throws Exception{                    inputs.add(stream);        OPCPackage srcPackage = OPCPackage.open(stream);        XWPFDocument src1Document = new XWPFDocument(srcPackage);                 if(inputs.size() == 1){            first = src1Document;        } else {                        CTBody srcBody = src1Document.getDocument().getBody();            first.getDocument().addNewBody().set(srcBody);                    }            }    public void doMerge() throws Exception{        first.write(result);                    }    public void close() throws Exception{        result.flush();        result.close();        for (InputStream input : inputs) {            input.close();        }    }   }

And its use:

public static void main(String[] args) throws Exception {    FileOutputStream faos = new FileOutputStream("/home/victor/result.docx");    WordMerge wm = new WordMerge(faos);    wm.add( new FileInputStream("/home/victor/001.docx") );    wm.add( new FileInputStream("/home/victor/002.docx") );    wm.doMerge();    wm.close();}


I have a suggestion!First the main method; the parameters are: test1=firstDocxFileName, test2=secondDocxFileName, dest=destinationFileName; document is a global variable;

    public void mergeDocx(String test1, String test2, String dest){    try {        XWPFDocument doc1 = new XWPFDocument(new FileInputStream(new File(test1)));        XWPFDocument doc2 = new XWPFDocument(new FileInputStream(new File(test2)));        document = new XWPFDocument();        passaElementi(doc1);        passaElementi(doc2);        passaStili(doc1,doc2);        OutputStream out = new FileOutputStream(new File(dest));        document.write(out);        out.close();    } catch (FileNotFoundException e) {        // TODO Auto-generated catch block        e.printStackTrace();    } catch (IOException e) {        // TODO Auto-generated catch block        e.printStackTrace();    }}

The private method 'passaElementi'copies and paste the body elements from doc1 to document object;I don't know what is XWPFSDT object...; (pay attention: i don't copy all the document but only the body!! .. for headers, sections, footers it proceed similarly) (the integer variables i and j are global and 0 at the beginning obviously)

private void passaElementi(XWPFDocument doc1){    for(IBodyElement e : doc1.getBodyElements()){        if(e instanceof XWPFParagraph){            XWPFParagraph p = (XWPFParagraph) e;            if(p.getCTP().getPPr()!=null && p.getCTP().getPPr().getSectPr()!=null){                continue;            }else{                document.createParagraph();                document.setParagraph(p, i);                i++;            }        }else if(e instanceof XWPFTable){            XWPFTable t = (XWPFTable)e;            document.createTable();            document.setTable(j, t);            j++;        }else if(e instanceof XWPFSDT){            // boh!        }    }}

The private method 'passaStili' copies and paste styles from doc1 and doc2 to document object;

private void passaStili(XWPFDocument doc1, XWPFDocument doc2){    try {        CTStyles c1 = doc1.getStyle();        CTStyles c2 =  doc2.getStyle();        int size1 = c1.getStyleList().size();        int size2 = c2.getStyleList().size();        for(int i = 0; i<size2; i++ ){            c1.addNewStyle();            c1.setStyleArray(size1+i, c2.getStyleList().get(i));        }        document.createStyles().setStyles(c1);    } catch (XmlException e) {        // TODO Auto-generated catch block        e.printStackTrace();    } catch (IOException e) {        // TODO Auto-generated catch block        e.printStackTrace();    }}

I don't handle exceptions to be fast! Leave a like if you liked it!Best regards!

B.M.


You should use XWPFDocument instead of HWPFDocument.

The documentation states:

The partner to HWPF for the new Word 2007 .docx format is XWPF. Whilst HWPF and XWPF provide similar features, there is not a common interface across the two of them at this time.

Change your code to:

XWPFDocument doc = new XWPFDocument(new FileInputStream("..."));XWPFDocument doc2 = new XWPFDocument(new FileInputStream("...")); XWPFDocument doc3 = new XWPFDocument(new FileInputStream("..."));