Use docx4j to merge multiple docx files into one docx file

Introduction

Use docx4j to merge multiple docx files into one docx file, and append content to the last paragraph of the document.

rely

     <dependency>
                <groupId>org.docx4j</groupId>
                <artifactId>docx4j</artifactId>
                <version>6.1.2</version>
            </dependency>

tool method

import org.apache.commons.io.IOUtils;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.WordprocessingML.AlternativeFormatInputPart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.wml.CTAltChunk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.List;


/**
 * @author gongl
 * @date 2022-10-10
 */
public class PdfUtils {
    
    
    private static final Logger log = LoggerFactory.getLogger(PdfUtils.class);

    /**
     * 合并word文件
     * @param wordList    待合并文件集合
     * @param outFilePath  输出文件路径
     */
    public static void mergeDoc(List<String> wordList, String outFilePath) {
    
    
        List<InputStream> streamList = new ArrayList<>();
        for (String wordPath : wordList) {
    
    
            try {
    
    
                streamList.add(new FileInputStream(wordPath));
            } catch (FileNotFoundException e) {
    
    
                log.error("待合并文件流读取异常:", e);
                e.printStackTrace();
            }
        }
        try {
    
    
            mergeDocStream(streamList, new FileOutputStream(new File(outFilePath)));
        } catch (Exception e) {
    
    
            log.error("临时文件创建异常:", e);
        }
    }

    private static void mergeDocStream(List<InputStream> streamList, FileOutputStream out) throws Docx4JException, IOException {
    
    
        WordprocessingMLPackage target = null;
        final File generated = File.createTempFile("generated", ".docx");
        int chunkId = 0;
        for (InputStream is : streamList) {
    
    
            if (is != null) {
    
    
                if (target == null) {
    
    
                    OutputStream os = new FileOutputStream(generated);
                    os.write(IOUtils.toByteArray(is));
                    os.close();
                    target = WordprocessingMLPackage.load(generated);
                } else {
    
    
                    insertDoc(target.getMainDocumentPart(), IOUtils.toByteArray(is), chunkId++);
                }
            }
        }
        if (target != null) {
    
    
            target.save(generated);
            FileInputStream fileInputStream = new FileInputStream(generated);
            saveTemplate(fileInputStream, out);
        }
    }

    private static void insertDoc(MainDocumentPart mainDocumentPart, byte[] bytes, int chunkId) {
    
    
        try {
    
    
            PartName partName = new PartName("/part" + chunkId + ".docx");
            AlternativeFormatInputPart afiPart = new AlternativeFormatInputPart(partName);
            afiPart.setBinaryData(bytes);
            Relationship relationship = mainDocumentPart.addTargetPart(afiPart);
            CTAltChunk chunk = Context.getWmlObjectFactory().createCTAltChunk();
            chunk.setId(relationship.getId());
            mainDocumentPart.addObject(chunk);
        } catch (Exception e) {
    
    
            log.error("文件合并临时文件异常:", e);
        }
    }

    private static void saveTemplate(InputStream targetStream, FileOutputStream out) {
    
    
        int byteread;
        try {
    
    
            byte[] buffer = new byte[1024 * 10];
            while ((byteread = targetStream.read(buffer)) != -1) {
    
    
                out.write(buffer, 0, byteread);
            }
            targetStream.close();
            out.close();
        } catch (IOException e) {
    
    
            log.error("生成文件异常:", e);
        }
    }
}

test case

First create two docx files: 2.docx and 1.docx
insert image description here

insert image description here

The execution code is merged into 3.docx

  public static void main(String[] args) {
    
    
        mergeDoc(Arrays.asList("C:\\Users\\E490\\Desktop\\2.docx", "C:\\Users\\E490\\Desktop\\1.docx"), 
        "C:\\Users\\E490\\Desktop\\3.docx");
    }

The result is as shown below
insert image description here

Guess you like

Origin blog.csdn.net/weixin_47914635/article/details/127243964