1. 程式人生 > >Java POI合併多個word檔案

Java POI合併多個word檔案

對於多個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);
	}