通過POI操作Word模版文檔


1.添加Maven依賴

<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
</dependency>

2.Word文檔模版中以${xxx}為替換字符,例如:

3.處理代碼

import org.apache.poi.xwpf.usermodel.*;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CreateWordUtil {

    /**
     * 替換文檔中的的變量
     * @param doc
     * @param params
     */
    public void replaceInDoc(XWPFDocument doc, Map<String, Object> params) {
        Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
        XWPFParagraph para;

        while (iterator.hasNext()) {
            para = iterator.next();

            this.replaceInPara(para, params,"0");
        }
    }

    /**
     * 替換表格里面的變量
     * @param doc
     * @param params
     */
    public void replaceInTable(XWPFDocument doc, Map<String, Object> params) {
        Iterator<XWPFTable> iterator = doc.getTablesIterator();
        XWPFTable table;
        List<XWPFTableRow> rows;
        List<XWPFTableCell> cells;
        List<XWPFParagraph> paras;

        while (iterator.hasNext()) {
            table = iterator.next();
            rows = table.getRows();

            for (XWPFTableRow row : rows) {
                cells = row.getTableCells();

                for (XWPFTableCell cell : cells) {
                    paras = cell.getParagraphs();

                    for (XWPFParagraph para : paras) {
                        this.replaceInPara(para, params, "0");
                    }
                }
            }
        }
    }

    /**
     * 替換頁眉
     * @param doc
     * @param params
     */
    public void replaceInHeader(XWPFDocument doc, Map<String, Object> params) {
        List<XWPFHeader> xwpfHeaderList = doc.getHeaderList();
        Iterator iterator = xwpfHeaderList.iterator();
        XWPFParagraph para;
        XWPFHeader xwpfHeader;

        while (iterator.hasNext()) {
            xwpfHeader = (XWPFHeader) iterator.next();
            List<XWPFParagraph> xwpfParagraphList = xwpfHeader.getParagraphs();
            Iterator iteratorPara = xwpfParagraphList.iterator();

            while (iteratorPara.hasNext()){
                para = (XWPFParagraph) iteratorPara.next();

                this.replaceInPara(para, params, "1");
            }
        }


    }

    /**
     * 替換段落里面的變量
     * @param para
     * @param params
     * @param type
     */
    private void replaceInPara(XWPFParagraph para, Map<String, Object> params, String type) {
        List<XWPFRun> runs;

        if (this.matcher(para.getParagraphText()).find()) {
            runs = para.getRuns();

            int start = -1;
            int end = -1;
            String str = "";

            for (int i = 0; i < runs.size(); i++) {
                XWPFRun run = runs.get(i);
                String runText = run.toString();

                System.out.println("runText==>"+runText);

                if(runText.length()>1){
                    if ('$' == runText.charAt(0) && '{' == runText.charAt(1) ) {
                        start = i;
                    }
                }else{
                    if ('$' == runText.charAt(0)){//解決頁眉問題
                        start = i;
                    }
                }


                if ((start != -1)) {
                    str += runText;
                }

                if ('}' == runText.charAt(runText.length() - 1)) {
                    if (start != -1) {
                        end = i;
                        break;
                    }
                }
            }


            for (int i = start; i <= end; i++) {
                para.removeRun(i);
                i--;
                end--;
            }

            for (String key : params.keySet()) {

                if (str.equals(key)) {
                    String text = ""+params.get(key);

                    XWPFRun  run = para.createRun();

                    if(type.equals("1")){//表示頁眉
                        run.setFontSize(10);
                    }else{
                        run.setFontSize(14);
                    }

                    run.setFontFamily("宋體");


                    if(text.indexOf("\r\n") >0 ){
                        String [] texts = text.split("\r\n");

                        for(int k=0; k<texts.length; k++){
                            if(k > 0 ){
                                //run.addCarriageReturn();//硬回車
                                // 換行
                                run.addBreak();
                            }

                            run.setText(text);
                        }
                    }else{
                        run.setText(text);
                    }

                    break;
                }
            }
        }
    }



    private Matcher matcher(String str) {
        Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);

        Matcher matcher = pattern.matcher(str);

        return matcher;
    }
}

 

4.測試

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

@Controller
@RestController
@RequestMapping(value = "/word/")
public class WordServer {

    @Autowired
    HttpServletRequest request;

    @GetMapping("/test")
    public ResponseEntity<?> test(){
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("${ywbh}", "YW202011290005");
        params.put("${xmmc}", "項目名稱");
        params.put("${sxkh}", "授信客戶");
        params.put("${jwgys}", "境外供應商");
        params.put("${myzt}", "貿易主體");
        params.put("${wlfw}", "物流服務");
        params.put("${sjht}", "涉及合同");
        params.put("${ywbj}", "\t對象識別的應用范圍比較廣,例如人臉識別,車牌識別,自動駕駛等等都用到了對象識別的技術。對象識別是當今機器學習領域的一個前沿,2017 年研發出來的 Mask-RCNN 模型還可以檢測對象的輪廓。");
        params.put("${ywms}", "\t如果圖片包含了多個物體,我們想識別有哪些物體,各個物體在什么位置,那么只用 CNN 模型是無法實現的。\r\n我們需要可以找出圖片哪些區域包含物體並且判斷每個區域包含什么物體的模型,這樣的模型稱為對象識別模型 (Object Detection Model),最早期的對象識別模型是 RCNN 模型,后來又發展出 Fast-RCNN (SPPnet),Faster-RCNN ,和 YOLO 等模型。因為對象識別需要處理的數據量多,速度會比較慢 (例如 RCNN 檢測單張圖片包含的物體可能需要幾十秒),而對象識別通常又要求實時性 (例如來源是攝像頭提供的視頻),所以如何提升對象識別的速度是一個主要的命題,后面發展出的 Faster-RCNN 與 YOLO 都可以在一秒鍾檢測幾十張圖片。");

        CreateWordUtil createWordUtil = new CreateWordUtil();

        XWPFDocument doc = null;
        String fileNameInResource = "審批單-模版.docx";
        InputStream is = getClass().getClassLoader().getResourceAsStream(fileNameInResource);

        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");

        String fileName = System.currentTimeMillis()+".docx";
        //String fileName = System.currentTimeMillis()+".pdf";

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        byte [] result = null;

        try {
            doc = new XWPFDocument(is);

            //替換頁眉
            createWordUtil.replaceInHeader(doc, params);
            //替換文檔中的段落
            //createWordUtil.replaceInDoc(doc, params);
            //替換文檔中的表格
            createWordUtil.replaceInTable(doc, params);

            doc.write(baos);

            result = baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                baos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if(null != doc){
                    try {
                        doc.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        headers.add("Content-Disposition", String.format("attachment; filename=\"%s\"", fileName));

        //將生成的Word文檔轉換為PDF
//        InputStream fileInput = new ByteArrayInputStream(result);
//        byte [] outputBytes = null;
//
//        try {
//            outputBytes = WordToPdfUtil.convert(fileInput);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

        return ResponseEntity
                .ok()
                .headers(headers)
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(new InputStreamResource(new ByteArrayInputStream(result)));
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM