使用java更新word模板文件的內容和圖片

使用java更新word模板文件的內容和圖片


上一篇博客我實現了更新word模板裏面的文字內容,但是,產品經理又有了新的想法,覺得只有文字的word文檔看起來比較單調,需要穿插一些圖片,師文字看起來更豐富多彩。

代碼實現

模板的定義我們參考上一篇文章:https://blog.csdn.net/lingfeian/article/details/103309379

以下代碼就是我們實現該功能的提取出來的工具類,在代碼中有詳細的註解,再此就不做過多的描述了。


/**
 * @author FeianLing
 * @date 2019/11/30
 * 通過模板生成新的word工具類
 */
@Component
public class WordUtils {
    /**
     * 根據模板生成word
     *
     * @param path           模板的路徑
     * @param params         需要替換的參數
     * @param exportFilePath 生成word文件的文件名
     */
    public File getWord(String path, Map<String, Object> params, String exportFilePath) throws Exception {

        InputStream is = new FileInputStream(new File(path));
        MyXWPFDocument doc = new MyXWPFDocument(is);
        replaceInPara(doc, params);    //替換文本里面的變量
        File exportFile = new File(exportFilePath);
        if (!exportFile.getParentFile().exists()) {
            exportFile.getParentFile().mkdirs();
        }
        if (!exportFile.exists()) {
            exportFile.createNewFile();
        }
        FileOutputStream fos = new FileOutputStream(exportFile);
        doc.write(fos);
        close(fos);
        close(is);
        return exportFile;
    }

    /**
     * @author FeianLing
     * @date 2019/12/3
     * @desc 替換段落裏面的內容
     * @param 
     * @param doc
     * @param params
     * @return void
     */
    private void replaceInPara(MyXWPFDocument doc, Map<String, Object> params) {
        Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
        XWPFParagraph para;
        while (iterator.hasNext()) {
            para = iterator.next();
            replaceInPara(para, params, doc);
        }
    }

	 /**
     * @author FeianLing
     * @date 2019/12/3
     * @desc 替換變量的內容
     * @param 
     * @param para
     * @param params
     * @param doc
     * @return void
     */
    private void replaceInPara(XWPFParagraph para, Map<String, Object> params, MyXWPFDocument doc) {
        List<XWPFRun> runs;
        Matcher matcher;
        String runText = "";
        if (matcher(para.getParagraphText()).find()) {
            runs = para.getRuns();
            if (runs.size() > 0) {
                int j = runs.size();
                for (int i = 0; i < j; i++) {
                    XWPFRun run = runs.get(0);
                    String i1 = run.toString();
                    runText = runText + i1;
                    para.removeRun(0);
                }
            }
            Logs.info("runText: {}", runText);
            matcher = matcher(runText);
            if (matcher.find()) {
                int count = 0;
                while ((matcher = matcher(runText)).find()) {
                    count = matcher.groupCount();
                    Object val = params.get(matcher.group()) == null ? "" : params.get(matcher.group());
                    if (val instanceof String) {
                        Logs.info("{} 替換成 {}", matcher.group(), params.get(matcher.group()));
                        runText = matcher.replaceFirst(String.valueOf(params.get(matcher.group())));
                    } else if (val instanceof Map) {
                        runText = matcher.replaceFirst("");
                        Map pic = (Map) val;
                        int width = Integer.parseInt(pic.get("width").toString());
                        int height = Integer.parseInt(pic.get("height").toString());
                        int picType = WordUtils.getPictureType(pic.get("type").toString());
                        byte[] byteArray = (byte[]) pic.get("content");
                        ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray);
                        try {
                            doc.addPictureData(byteInputStream, picType);
                            doc.createPicture(doc.getAllPictures().size() - 1, width, height, para);
                            para.createRun().setText("\n", 0);
                        } catch (Exception e) {
                            Logs.error(e.getMessage());
                        }
                        break;
                    } else {
                        Logs.info("參數類型未識別" + val.getClass());
                        break;
                    }
                }
                // 直接調用XWPFRun的setText()方法設置文本時,在底層會重新創建一個XWPFRun,把文本附加在當前文本後面,
                // 所以我們不能直接設值,需要先刪除當前run,然後再自己手動插入一個新的run。
                para.insertNewRun(0).setText(runText);
            }
        }
    }

    /**
     * @author FeianLing
     * @date 2019/12/3
     * @desc 正則匹配字符串
     * @param 
     * @param str
     * @return java.util.regex.Matcher
     */
    private Matcher matcher(String str) {
        Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(str);
        return matcher;
    }


    /**
     * @author FeianLing
     * @date 2019/12/3
     * @desc 根據圖片類型,取得對應的圖片類型代碼
     * @param 
     * @param picType
     * @return int
     */
    private static int getPictureType(String picType) {
        int res = MyXWPFDocument.PICTURE_TYPE_PICT;
        if (picType != null) {
            if (picType.equalsIgnoreCase("png")) {
                res = MyXWPFDocument.PICTURE_TYPE_PNG;
            } else if (picType.equalsIgnoreCase("dib")) {
                res = MyXWPFDocument.PICTURE_TYPE_DIB;
            } else if (picType.equalsIgnoreCase("emf")) {
                res = MyXWPFDocument.PICTURE_TYPE_EMF;
            } else if (picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")) {
                res = MyXWPFDocument.PICTURE_TYPE_JPEG;
            } else if (picType.equalsIgnoreCase("wmf")) {
                res = MyXWPFDocument.PICTURE_TYPE_WMF;
            }
        }
        return res;
    }

    /**
     * @author FeianLing
     * @date 2019/12/3
     * @desc 將輸入流中的數據寫入字節數組
     * @param 
     * @param is
     * @param isClose
     * @return byte[]
     */
    public static byte[] inputStream2ByteArray(InputStream is, boolean isClose) {
        byte[] byteArray = null;
        try {
            int total = is.available();
            byteArray = new byte[total];
            is.read(byteArray);
        } catch (IOException e) {
            Logs.error(e.getMessage(),e);
        } finally {
            if (isClose) {
                try {
                    is.close();
                } catch (Exception e2) {
                    Logs.error(e2.getMessage(),e2);
                }
            }
        }
        return byteArray;
    }


    /**
     * @author FeianLing
     * @date 2019/12/3
     * @desc 關閉輸入流
     * @param 
     * @param is
     * @return void
     */
    private void close(InputStream is) {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                Logs.error(e.getMessage(),e);
            }
        }
    }

    /**
     * @author FeianLing
     * @date 2019/12/3
     * @desc 關閉輸出流
     * @param 
     * @param os
     * @return void
     */
    private void close(OutputStream os) {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                Logs.error(e.getMessage(),e);
            }
        }
    }
}

圖片的變量,我們使用一個map類型封裝,可以參考下面這段代碼,圖片的大小根據情況設定。

  Logs.info("markImgPath > " + markImgPath);
                Map<String, Object> markImg = new HashMap<String, Object>();
                markImg.put("width", 336);
                markImg.put("height", 140);
                markImg.put("type", "jpg");
                markImg.put("content", WordUtils.inputStream2ByteArray(new FileInputStream(markImgPath), true));
                dataMap.put("${markImg}", markImg);

done

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章