1. 程式人生 > >Spring Boot中使用freeMarker生成word文件

Spring Boot中使用freeMarker生成word文件

前面介紹了Java POI方式來生成Word文件,今天用另一種方式來生成。使用freeMarker的方式來生成。使用freeMarker的方式來生成的過程具體如下。

在maven pom.xml檔案中加入freeMarker,我這裡是在maven環境下做的例子,用其他方式的小夥伴也可以直接到官網下載jar包。

<!--新增freeMarker-->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.20</version>
        </dependency>
下一步我們要做的是先好我們的word模板然後將模板轉換為xml檔案。在word模板中需要定義好我們的佔位符哦,使用${string}的方式。“string”根據自己的愛好定義就好了。

過程如下:

word文件:

word-1

然後將我們的word文件另存為xml文件。

xml-1
將我們的xml文件的字尾改為ftl,然後用可以開啟ftl檔案的軟體開啟我們的ftl檔案。在這裡我們有幾個需要注意的地方。

第一,定義的佔位符可能會被分開了。就像下面這樣:

zwf-1

我們需要做的就是刪掉多餘的部分,圖中我定義的是${userName}.所以我就把多餘的刪掉,變成${userName}就可以了。

第二,我們需要注意的就是在我們的表格部分需要自己新增freeMarker標籤。在表格程式碼間用自定的標籤括起來。定義的引數要和我們在方法中定義的一致,否則無法取到值。

表格開始:

list-1

結束:

list-2

引數:

p-1

這樣我們的模板就完成了。

將我們的模板文件放到我們的檔案結構下就。但是Spring boot讀取靜態資源和其他方式的讀取型別不一致哦,如果是Spring boot開發的小夥伴需要注意下一。不懂的自己去網上查閱一下就會明白了。其他方式的小夥伴根據自己的檔案結構修改一下就好了。我這裡的是直接放在resources資料夾下的。所以我這裡的獲取路徑是這樣寫的。

r-1

r-2

Java程式碼如下:

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by zhouhs on 2017/1/10.
 */
@SuppressWarnings("serial")
public class WordAction {

    private String filePath; //檔案路徑
    private String fileName; //檔名稱
    private String fileOnlyName; //檔案唯一名稱


    public String createWord() {
        /** 用於組裝word頁面需要的資料 */
        Map<String, Object> dataMap = new HashMap<String, Object>();

        /** 組裝資料 */
        dataMap.put("userName", "seawater");

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        dataMap.put("date", sdf.format(new Date()));

        dataMap.put("content", "freeMark生成Word文件段落內容");

        List<Map<String, Object>> listInfo = new ArrayList<Map<String, Object>>();
        for (int i = 1; i <= 10; i++) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("title", "標題" + i);
            map.put("content", "內容" + i);
            map.put("author", "作者" + i);
            listInfo.add(map);
        }
        dataMap.put("listInfo", listInfo);

        /** 檔名稱,唯一字串 */
        Random r = new Random();
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd");
        StringBuffer sb = new StringBuffer();
        sb.append(sdf1.format(new Date()));
        sb.append("_");
        sb.append(r.nextInt(100));

        //檔案路徑
        filePath = "D:/doc_f/";

        //檔案唯一名稱
        fileOnlyName = "用freemarker生成Word文件_" + sb + ".doc";

        //檔名稱
        fileName = "用freemarker生成Word文件.doc";

        /** 生成word */
        WordUtil.createWord(dataMap, "freeMark.ftl", filePath, fileOnlyName);

        return "createWordSuccess";
    }


    /**
     *
     * 下載生成的word文件
     */
    public String dowloadWord() {
        /** 先判斷檔案是否已生成  */
        try {
            //解決中文亂碼
            filePath = URLDecoder.decode(filePath, "UTF-8");
            fileOnlyName = URLDecoder.decode(fileOnlyName, "UTF-8");
            fileName = URLDecoder.decode(fileName, "UTF-8");

            //如果檔案不存在,則會跳入異常,然後可以進行異常處理
            new FileInputStream(filePath + File.separator + fileOnlyName);
        } catch (Exception e) {
            e.printStackTrace();
            return "error";
        }
        return "dowloadWord";
    }

    /**
     * 返回最終生成的word文件 檔案流
     * 下載生成的word文件
     */
    public InputStream getWordFile() {
        try {
            //解決中文亂碼
            fileName = URLDecoder.decode(fileName, "UTF-8");

            /** 返回最終生成的word檔案流  */
            return new FileInputStream(filePath + File.separator + fileOnlyName);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    public String getFilePath() {
        return filePath;
    }


    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }


    public String getFileName() {
        return fileName;
    }


    public void setFileName(String fileName) {
        this.fileName = fileName;
    }


    public String getFileOnlyName() {
        return fileOnlyName;
    }


    public void setFileOnlyName(String fileOnlyName) {
        this.fileOnlyName = fileOnlyName;
    }
}
工具類:
import freemarker.template.Configuration;
import freemarker.template.Template;

import java.io.*;
import java.util.Map;

public class WordUtil {

    /**
     * 生成word檔案
     * @param dataMap word中需要展示的動態資料,用map集合來儲存
     * @param templateName word模板名稱,例如:test.ftl
     * @param filePath 檔案生成的目標路徑,例如:D:/wordFile/
     * @param fileName 生成的檔名稱,例如:test.doc
     */
    @SuppressWarnings("unchecked")
    public static void createWord(Map dataMap,String templateName,String filePath,String fileName){
        try {
            //建立配置例項
            Configuration configuration = new Configuration();

            //設定編碼
            configuration.setDefaultEncoding("UTF-8");

            //ftl模板檔案
            configuration.setClassForTemplateLoading(WordUtil.class,"/");

            //獲取模板
            Template template = configuration.getTemplate(templateName);

            //輸出檔案
            File outFile = new File(filePath+File.separator+fileName);

            //如果輸出目標資料夾不存在,則建立
            if (!outFile.getParentFile().exists()){
                outFile.getParentFile().mkdirs();
            }

            //將模板和資料模型合併生成檔案
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8"));


            //生成檔案
            template.process(dataMap, out);

            //關閉流
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
訪問方式就根據自己的需求去訪問。

生成的文件如下:

word-n

word-c

到這裡我們在Spring boot中使用freeMarker生成word文件就完成了。