对于多个docx文件,可以使用POI合并生成一个组合的docx文件,这个方法分享给大家。不过对于docx文件中存在有图片的文档,此种方法没有做处理,需要的朋友可以自己扩展一下。
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
/**
* 合并两个docx文档方法,对文档包含的图片无效
* @author laitong.ma
* @date 2018年9月17日
*/
public class POIMergeDocUtil {
public static void main(String[] args) throws Exception {
String[] srcDocxs = {"e:\\waxz_1.docx","e:\\waxz_2.docx","e:\\waxz_3.docx"};
String destDocx = "e:\\wzxz_new.docx";
mergeDoc(srcDocxs, destDocx);
}
/**
* 合并docx文件
* @param srcDocxs 需要合并的目标docx文件
* @param destDocx 合并后的docx输出文件
*/
public static void mergeDoc(String[] srcDocxs,String destDocx){
OutputStream dest = null;
List<OPCPackage> opcpList = new ArrayList<OPCPackage>();
int length = null == srcDocxs ? 0 : srcDocxs.length;
/**
* 循环获取每个docx文件的OPCPackage对象
*/
for (int i = 0; i < length; i++) {
String doc = srcDocxs[i];
OPCPackage srcPackage = null;
try {
srcPackage = OPCPackage.open(doc);
} catch (Exception e) {
e.printStackTrace();
}
if(null != srcPackage){
opcpList.add(srcPackage);
}
}
int opcpSize = opcpList.size();
//获取的OPCPackage对象大于0时,执行合并操作
if(opcpSize > 0){
try {
dest = new FileOutputStream(destDocx);
XWPFDocument src1Document = new XWPFDocument(opcpList.get(0));
CTBody src1Body = src1Document.getDocument().getBody();
//OPCPackage大于1的部分执行合并操作
if(opcpSize > 1){
for (int i = 1; i < opcpSize; i++) {
OPCPackage src2Package = opcpList.get(i);
XWPFDocument src2Document = new XWPFDocument(src2Package);
CTBody src2Body = src2Document.getDocument().getBody();
appendBody(src1Body, src2Body);
}
}
//将合并的文档写入目标文件中
src1Document.write(dest);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}finally{
//注释掉以下部分,去除影响目标文件srcDocxs。
/*for (OPCPackage opcPackage : opcpList) {
if(null != opcPackage){
try {
opcPackage.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}*/
//关闭流
IOUtils.closeQuietly(dest);
}
}
}
/**
* 合并文档内容
* @param src 目标文档
* @param append 要合并的文档
* @throws Exception
*/
private static void appendBody(CTBody src, CTBody append) throws Exception {
XmlOptions optionsOuter = new XmlOptions();
optionsOuter.setSaveOuter();
String appendString = append.xmlText(optionsOuter);
String srcString = src.xmlText();
String prefix = srcString.substring(0, srcString.indexOf(">") + 1);
String mainPart = srcString.substring(srcString.indexOf(">") + 1,
srcString.lastIndexOf("<"));
String sufix = srcString.substring(srcString.lastIndexOf("<"));
String addPart = appendString.substring(appendString.indexOf(">") + 1,
appendString.lastIndexOf("<"));
CTBody makeBody = CTBody.Factory.parse(prefix + mainPart + addPart
+ sufix);
src.set(makeBody);
}