FreeMarker模板引擎

qch發表於2021-07-09

  前言

  FreeMarker是一款模板引擎,即一種基於模板和要改變的資料,並用來生成輸出文字的通用工具。

  官方文件:http://freemarker.foofun.cn

  

  日常開發中,我們會有這樣的需求:

  1、在頁面上填寫資料並匯出word文件、後臺批量設定資料並匯出Excel文件(例如我們之前的部落格記錄:html頁面轉PDF、圖片操作記錄

  2、寫一個程式碼生成工具(例如我們之前的部落格記錄:寫一個簡單的程式碼生成器

 

  這種情況下我們可以用FreeMarker模板引擎來實現,本文記錄FreeMarker簡單操作。

 

  程式碼編寫

  maven引入依賴

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.31</version>
</dependency>

 

  Word/Excel操作

  Word操作

  例如,要匯出員工檔案,格式如下:

 

 

   我們先按照格式要求,寫好word文件,然後另存為xml,得到模板檔案

 

 

   用idea開啟word.xml,格式化一下,然後根據FreeMarker的語法表示式讀取、設定值

 

 

   封裝一個方法

    //Word文件操作
    private static void createWord(){
        System.out.println("開始Word文件操作...");

        //指定TemplateLoading模板根路徑
        String rootPath = "E:\\Java\\test\\";
        //模板檔案
        String templatePath = "word.xml";
        //最終輸出檔案路徑
        String outFilePath = rootPath+"word_by_freemarker.docx";
        //資料
        Map<String, Object> data = new HashMap<>();
        data.put("company","某某公司");
        data.put("number","0001");
        data.put("name","huanzi-qch");
        data.put("phone","15600000000");
        data.put("department","軟體開發部");
        data.put("post","開發工程師");
        ArrayList<Map<String, String>> works = new ArrayList<>();
        Map<String, String> work1 = new HashMap<>();
        work1.put("company","某某單位1");
        work1.put("time","2018-01 - 2019-01");
        work1.put("department","研發1部");
        work1.put("post","開發工程師");
        works.add(work1);
        Map<String, String> work2 = new HashMap<>();
        work2.put("company","某某單位2");
        work2.put("time","2019-01 - 2020-01");
        work2.put("department","研發2部");
        work2.put("post","開發工程師");
        works.add(work2);
        data.put("works",works);

        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFilePath), StandardCharsets.UTF_8));){
            //初始化,指定版本與pom檔案相同
            Configuration configuration = new Configuration(new Version("2.3.31"));
            configuration.setDefaultEncoding(StandardCharsets.UTF_8.toString());
            configuration.setDirectoryForTemplateLoading(new File(rootPath));
            Template template = configuration.getTemplate(templatePath);

            //處理(資料)
            template.process(data, writer);
        } catch (IOException | TemplateException e) {
            e.printStackTrace();
        }

        System.out.println("Word文件操作結束!");
    }

 

  效果

 

 

 

 

 

  Excel操作

  Excel操作同理,也是先建立一個例子,另存為xml格式,再根據FreeMarker的語法表示式設定值

  按照欄位名,建Excel例子時直接把取值程式碼寫進去,轉成xml後就可能省一點時間

 

 

 

 

 

 

   同樣,idea開啟後格式化一下,遍歷設定值

 

 

   封裝一個方法

    //Excel文件操作
    private static void createExcel(){
        System.out.println("開始Excel文件操作...");

        //指定TemplateLoading模板根路徑
        String rootPath = "E:\\Java\\test\\";
        //模板檔案
        String templatePath = "excel.xml";
        //最終輸出檔案路徑
        String outFilePath = rootPath+"excel_by_freemarker.xlsx";
        //資料
        Map<String, Object> data = new HashMap<>();
        ArrayList<Map<String, String>> persons = new ArrayList<>();
        Map<String, String> person1 = new HashMap<>();
        person1.put("name","huanzi-qch1");
        person1.put("phone","15600000000");
        person1.put("company","某某單位1");
        person1.put("time","2018-01 - 2019-01");
        person1.put("department","研發1部");
        person1.put("post","開發工程師");
        persons.add(person1);
        Map<String, String> person2 = new HashMap<>();
        person2.put("name","huanzi-qch2");
        person2.put("phone","15600000000");
        person2.put("company","某某單位2");
        person2.put("time","2019-01 - 2020-01");
        person2.put("department","研發2部");
        person2.put("post","開發工程師");
        persons.add(person2);
        data.put("persons",persons);

        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFilePath), StandardCharsets.UTF_8));){
            //初始化,指定版本與pom檔案相同
            Configuration configuration = new Configuration(new Version("2.3.31"));
            configuration.setDefaultEncoding(StandardCharsets.UTF_8.toString());
            configuration.setDirectoryForTemplateLoading(new File(rootPath));
            Template template = configuration.getTemplate(templatePath);

            //處理(資料)
            template.process(data, writer);
        } catch (IOException | TemplateException e) {
            e.printStackTrace();
        }

        System.out.println("Excel文件操作結束!");
    }

 

  效果

 

 

 

 

 

 

  程式碼生成器

  程式碼生成器,先把我們之前寫好的JDBC連線資料庫工具類、字串處理工具類、表結構資訊實體類以及獲取表結構資訊的方法先拿過來

    /**
     * 程式自動設定
     */
    private static String tableName;//表名
    private static String tableComment;//表註釋

    /**
     * 資料連線相關,需要手動設定
     */
    private static final String URL = "jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&characterEncoding=utf-8";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "123456";
    private static final String DRIVER_CLASSNAME = "com.mysql.cj.jdbc.Driver";

    /**
     * 字串處理工具類
     */
    private static class StringUtil {
        /**
         * 資料庫型別->JAVA型別
         *
         * @param dbType 資料庫型別
         * @return JAVA型別
         */
        private static String typeMapping(String dbType) {
            String javaType;
            if ("int|integer".contains(dbType)) {
                javaType = "Integer";
            } else if ("float|double|decimal|real".contains(dbType)) {
                javaType = "Double";
            } else if ("date|time|datetime|timestamp".contains(dbType)) {
                javaType = "Date";
            } else {
                javaType = "String";
            }
            return javaType;
        }

        /**
         * 駝峰轉換為下劃線
         */
        private static String underscoreName(String camelCaseName) {
            StringBuilder result = new StringBuilder();
            if (camelCaseName != null && camelCaseName.length() > 0) {
                result.append(camelCaseName.substring(0, 1).toLowerCase());
                for (int i = 1; i < camelCaseName.length(); i++) {
                    char ch = camelCaseName.charAt(i);
                    if (Character.isUpperCase(ch)) {
                        result.append("_");
                        result.append(Character.toLowerCase(ch));
                    } else {
                        result.append(ch);
                    }
                }
            }
            return result.toString();
        }

        /**
         * 首字母大寫
         */
        private static String captureName(String name) {
            char[] cs = name.toCharArray();
            cs[0] -= 32;
            return String.valueOf(cs);

        }

        /**
         * 下劃線轉換為駝峰
         */
        private static String camelCaseName(String underscoreName) {
            StringBuilder result = new StringBuilder();
            if (underscoreName != null && underscoreName.length() > 0) {
                boolean flag = false;
                for (int i = 0; i < underscoreName.length(); i++) {
                    char ch = underscoreName.charAt(i);
                    if ("_".charAt(0) == ch) {
                        flag = true;
                    } else {
                        if (flag) {
                            result.append(Character.toUpperCase(ch));
                            flag = false;
                        } else {
                            result.append(ch);
                        }
                    }
                }
            }
            return result.toString();
        }
    }

    /**
     * JDBC連線資料庫工具類
     */
    private static class DBConnectionUtil {

        static {
            // 1、載入驅動
            try {
                Class.forName(DRIVER_CLASSNAME);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

        /**
         * 返回一個Connection連線
         */
        static Connection getConnection() {
            Connection conn = null;
            // 2、連線資料庫
            try {
                conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return conn;
        }

        /**
         * 關閉Connection,Statement連線
         */
        public static void close(Connection conn, Statement stmt) {
            try {
                conn.close();
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        /**
         * 關閉Connection,Statement,ResultSet連線
         */
        public static void close(Connection conn, Statement stmt, ResultSet rs) {
            try {
                close(conn, stmt);
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 表結構資訊實體類
     */
    private static class TableInfo {
        private String columnName;//欄位名
        private String dataType;//欄位型別
        private String columnComment;//欄位註釋
        private String columnKey;//主鍵
        private String extra;//主鍵型別

        public String getColumnName() {
            return columnName;
        }

        public void setColumnName(String columnName) {
            this.columnName = columnName;
        }

        public String getDataType() {
            return dataType;
        }

        public void setDataType(String dataType) {
            this.dataType = dataType;
        }

        public String getColumnComment() {
            return columnComment;
        }

        public void setColumnComment(String columnComment) {
            this.columnComment = columnComment;
        }

        public String getColumnKey() {
            return columnKey;
        }

        public void setColumnKey(String columnKey) {
            this.columnKey = columnKey;
        }

        public String getExtra() {
            return extra;
        }

        public void setExtra(String extra) {
            this.extra = extra;
        }
    }

    /**
     * 獲取表結構資訊
     * 目前僅支援mysql
     */
    private static List<TableInfo> getTableInfo() {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        ArrayList<TableInfo> list = new ArrayList<>();
        try {
            conn = DBConnectionUtil.getConnection();

            //表欄位資訊
            String sql = "select column_name,data_type,column_comment,column_key,extra from information_schema.columns where table_schema = (select database()) and table_name=?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, tableName);
            rs = ps.executeQuery();
            while (rs.next()) {
                TableInfo tableInfo = new TableInfo();
                //列名,全部轉為小寫
                tableInfo.setColumnName(rs.getString("column_name").toLowerCase());
                //列型別
                tableInfo.setDataType(rs.getString("data_type"));
                //列註釋
                tableInfo.setColumnComment(rs.getString("column_comment"));
                //主鍵
                tableInfo.setColumnKey(rs.getString("column_key"));
                //主鍵型別
                tableInfo.setExtra(rs.getString("extra"));
                list.add(tableInfo);
            }

            //表註釋
            sql = "select table_comment from information_schema.tables where table_schema = (select database()) and table_name=?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, tableName);
            rs = ps.executeQuery();
            while (rs.next()) {
                //表註釋
                tableComment = rs.getString("table_comment");
            }
        } catch (SQLException e) {

            e.printStackTrace();
        } finally {
            if(rs != null){
                DBConnectionUtil.close(conn, ps, rs);
            }
        }
        return list;
    }

  從原來的程式碼生成器那裡拿一個entity.tlf模板,小改動一下(主要是迴圈、if判斷那裡不一樣)

package cn.huanzi.qch.baseadmin.sys.${entityToLowerCase}.pojo;

import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

/**
 * ${tableComment} 實體類
 *
 * ${author}
 * ${date}
 */
@Entity
@Table(name = "${tableName}")
@Data
public class ${entity} implements Serializable {
  <#list tableInfos as tableInfo>
    <#if tableInfo.columnKey == "PRI">@Id</#if>
    <#if tableInfo.extra == "auto_increment">@GeneratedValue(strategy= GenerationType.IDENTITY)</#if>
    private ${tableInfo.dataType} ${tableInfo.columnName};//${tableInfo.columnComment}
  </#list>
}

  封裝一個方法

    //程式碼生成
    private static void autoGenerator(String tName){
        System.out.println("開始程式碼生成操作...");
        tableName = tName;

        //指定TemplateLoading模板根路徑
        String rootPath = "E:\\Java\\test\\";
        //模板檔案
        String templatePath = "entity.tlf";
        //最終輸出檔案路徑
        String outFilePath = rootPath+"entity.java";
        //資料
        Map<String, Object> data = new HashMap<>();
        //駝峰標識對映後的表名
        String captureName = StringUtil.captureName(StringUtil.camelCaseName(tableName));
        //獲取表資訊,並進行處理
        List<TableInfo> tableInfoList = getTableInfo();
        ArrayList<Map<String, String>> tableInfos = new ArrayList<>();
        for (TableInfo info : tableInfoList) {
            HashMap<String, String> hashMap = new HashMap<>();
            hashMap.put("columnName", StringUtil.camelCaseName(info.getColumnName()));
            hashMap.put("dataType", StringUtil.typeMapping(info.getDataType()));
            hashMap.put("columnComment", info.getColumnComment());
            hashMap.put("columnKey", info.getColumnKey());
            hashMap.put("extra", info.getExtra());
            tableInfos.add(hashMap);
        }
        data.put("entityToLowerCase",captureName.toLowerCase());
        data.put("tableComment",tableComment);
        data.put("author","作者:Auto Generator By 'huanzi-qch'");
        data.put("date","生成日期:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        data.put("tableName",tableName);
        data.put("entity",captureName);
        data.put("tableInfos",tableInfos);

        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFilePath), StandardCharsets.UTF_8));){
            //初始化,指定版本與pom檔案相同
            Configuration configuration = new Configuration(new Version("2.3.31"));
            configuration.setDefaultEncoding(StandardCharsets.UTF_8.toString());
            configuration.setDirectoryForTemplateLoading(new File(rootPath));
            Template template = configuration.getTemplate(templatePath);

            //處理(資料)
            template.process(data, writer);
        } catch (IOException | TemplateException e) {
            e.printStackTrace();
        }

        System.out.println("程式碼生成操作結束!");
    }

 

  效果

 

 

 

 

 

 

  完整程式碼

FreeMarker模板引擎
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.Version;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Date;

public class Test {

    //Word文件操作
    private static void createWord(){
        System.out.println("開始Word文件操作...");

        //指定TemplateLoading模板根路徑
        String rootPath = "E:\\Java\\test\\";
        //模板檔案
        String templatePath = "word.xml";
        //最終輸出檔案路徑
        String outFilePath = rootPath+"word_by_freemarker.docx";
        //資料
        Map<String, Object> data = new HashMap<>();
        data.put("company","某某公司");
        data.put("number","0001");
        data.put("name","huanzi-qch");
        data.put("phone","15600000000");
        data.put("department","軟體開發部");
        data.put("post","開發工程師");
        ArrayList<Map<String, String>> works = new ArrayList<>();
        Map<String, String> work1 = new HashMap<>();
        work1.put("company","某某單位1");
        work1.put("time","2018-01 - 2019-01");
        work1.put("department","研發1部");
        work1.put("post","開發工程師");
        works.add(work1);
        Map<String, String> work2 = new HashMap<>();
        work2.put("company","某某單位2");
        work2.put("time","2019-01 - 2020-01");
        work2.put("department","研發2部");
        work2.put("post","開發工程師");
        works.add(work2);
        data.put("works",works);

        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFilePath), StandardCharsets.UTF_8));){
            //初始化,指定版本與pom檔案相同
            Configuration configuration = new Configuration(new Version("2.3.31"));
            configuration.setDefaultEncoding(StandardCharsets.UTF_8.toString());
            configuration.setDirectoryForTemplateLoading(new File(rootPath));
            Template template = configuration.getTemplate(templatePath);

            //處理(資料)
            template.process(data, writer);
        } catch (IOException | TemplateException e) {
            e.printStackTrace();
        }

        System.out.println("Word文件操作結束!");
    }

    //Excel文件操作
    private static void createExcel(){
        System.out.println("開始Excel文件操作...");

        //指定TemplateLoading模板根路徑
        String rootPath = "E:\\Java\\test\\";
        //模板檔案
        String templatePath = "excel.xml";
        //最終輸出檔案路徑
        String outFilePath = rootPath+"excel_by_freemarker.xlsx";
        //資料
        Map<String, Object> data = new HashMap<>();
        ArrayList<Map<String, String>> persons = new ArrayList<>();
        Map<String, String> person1 = new HashMap<>();
        person1.put("name","huanzi-qch1");
        person1.put("phone","15600000000");
        person1.put("company","某某單位1");
        person1.put("time","2018-01 - 2019-01");
        person1.put("department","研發1部");
        person1.put("post","開發工程師");
        persons.add(person1);
        Map<String, String> person2 = new HashMap<>();
        person2.put("name","huanzi-qch2");
        person2.put("phone","15600000000");
        person2.put("company","某某單位2");
        person2.put("time","2019-01 - 2020-01");
        person2.put("department","研發2部");
        person2.put("post","開發工程師");
        persons.add(person2);
        data.put("persons",persons);

        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFilePath), StandardCharsets.UTF_8));){
            //初始化,指定版本與pom檔案相同
            Configuration configuration = new Configuration(new Version("2.3.31"));
            configuration.setDefaultEncoding(StandardCharsets.UTF_8.toString());
            configuration.setDirectoryForTemplateLoading(new File(rootPath));
            Template template = configuration.getTemplate(templatePath);

            //處理(資料)
            template.process(data, writer);
        } catch (IOException | TemplateException e) {
            e.printStackTrace();
        }

        System.out.println("Excel文件操作結束!");
    }

    //程式碼生成
    private static void autoGenerator(String tName){
        System.out.println("開始程式碼生成操作...");
        tableName = tName;

        //指定TemplateLoading模板根路徑
        String rootPath = "E:\\Java\\test\\";
        //模板檔案
        String templatePath = "entity.tlf";
        //最終輸出檔案路徑
        String outFilePath = rootPath+"entity.java";
        //資料
        Map<String, Object> data = new HashMap<>();
        //駝峰標識對映後的表名
        String captureName = StringUtil.captureName(StringUtil.camelCaseName(tableName));
        //獲取表資訊,並進行處理
        List<TableInfo> tableInfoList = getTableInfo();
        ArrayList<Map<String, String>> tableInfos = new ArrayList<>();
        for (TableInfo info : tableInfoList) {
            HashMap<String, String> hashMap = new HashMap<>();
            hashMap.put("columnName", StringUtil.camelCaseName(info.getColumnName()));
            hashMap.put("dataType", StringUtil.typeMapping(info.getDataType()));
            hashMap.put("columnComment", info.getColumnComment());
            hashMap.put("columnKey", info.getColumnKey());
            hashMap.put("extra", info.getExtra());
            tableInfos.add(hashMap);
        }
        data.put("entityToLowerCase",captureName.toLowerCase());
        data.put("tableComment",tableComment);
        data.put("author","作者:Auto Generator By 'huanzi-qch'");
        data.put("date","生成日期:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        data.put("tableName",tableName);
        data.put("entity",captureName);
        data.put("tableInfos",tableInfos);

        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFilePath), StandardCharsets.UTF_8));){
            //初始化,指定版本與pom檔案相同
            Configuration configuration = new Configuration(new Version("2.3.31"));
            configuration.setDefaultEncoding(StandardCharsets.UTF_8.toString());
            configuration.setDirectoryForTemplateLoading(new File(rootPath));
            Template template = configuration.getTemplate(templatePath);

            //處理(資料)
            template.process(data, writer);
        } catch (IOException | TemplateException e) {
            e.printStackTrace();
        }

        System.out.println("程式碼生成操作結束!");
    }

    /**
     * 程式自動設定
     */
    private static String tableName;//表名
    private static String tableComment;//表註釋

    /**
     * 資料連線相關,需要手動設定
     */
    private static final String URL = "jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&characterEncoding=utf-8";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "123456";
    private static final String DRIVER_CLASSNAME = "com.mysql.cj.jdbc.Driver";

    /**
     * 字串處理工具類
     */
    private static class StringUtil {
        /**
         * 資料庫型別->JAVA型別
         *
         * @param dbType 資料庫型別
         * @return JAVA型別
         */
        private static String typeMapping(String dbType) {
            String javaType;
            if ("int|integer".contains(dbType)) {
                javaType = "Integer";
            } else if ("float|double|decimal|real".contains(dbType)) {
                javaType = "Double";
            } else if ("date|time|datetime|timestamp".contains(dbType)) {
                javaType = "Date";
            } else {
                javaType = "String";
            }
            return javaType;
        }

        /**
         * 駝峰轉換為下劃線
         */
        private static String underscoreName(String camelCaseName) {
            StringBuilder result = new StringBuilder();
            if (camelCaseName != null && camelCaseName.length() > 0) {
                result.append(camelCaseName.substring(0, 1).toLowerCase());
                for (int i = 1; i < camelCaseName.length(); i++) {
                    char ch = camelCaseName.charAt(i);
                    if (Character.isUpperCase(ch)) {
                        result.append("_");
                        result.append(Character.toLowerCase(ch));
                    } else {
                        result.append(ch);
                    }
                }
            }
            return result.toString();
        }

        /**
         * 首字母大寫
         */
        private static String captureName(String name) {
            char[] cs = name.toCharArray();
            cs[0] -= 32;
            return String.valueOf(cs);

        }

        /**
         * 下劃線轉換為駝峰
         */
        private static String camelCaseName(String underscoreName) {
            StringBuilder result = new StringBuilder();
            if (underscoreName != null && underscoreName.length() > 0) {
                boolean flag = false;
                for (int i = 0; i < underscoreName.length(); i++) {
                    char ch = underscoreName.charAt(i);
                    if ("_".charAt(0) == ch) {
                        flag = true;
                    } else {
                        if (flag) {
                            result.append(Character.toUpperCase(ch));
                            flag = false;
                        } else {
                            result.append(ch);
                        }
                    }
                }
            }
            return result.toString();
        }
    }

    /**
     * JDBC連線資料庫工具類
     */
    private static class DBConnectionUtil {

        static {
            // 1、載入驅動
            try {
                Class.forName(DRIVER_CLASSNAME);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

        /**
         * 返回一個Connection連線
         */
        static Connection getConnection() {
            Connection conn = null;
            // 2、連線資料庫
            try {
                conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return conn;
        }

        /**
         * 關閉Connection,Statement連線
         */
        public static void close(Connection conn, Statement stmt) {
            try {
                conn.close();
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        /**
         * 關閉Connection,Statement,ResultSet連線
         */
        public static void close(Connection conn, Statement stmt, ResultSet rs) {
            try {
                close(conn, stmt);
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 表結構資訊實體類
     */
    private static class TableInfo {
        private String columnName;//欄位名
        private String dataType;//欄位型別
        private String columnComment;//欄位註釋
        private String columnKey;//主鍵
        private String extra;//主鍵型別

        public String getColumnName() {
            return columnName;
        }

        public void setColumnName(String columnName) {
            this.columnName = columnName;
        }

        public String getDataType() {
            return dataType;
        }

        public void setDataType(String dataType) {
            this.dataType = dataType;
        }

        public String getColumnComment() {
            return columnComment;
        }

        public void setColumnComment(String columnComment) {
            this.columnComment = columnComment;
        }

        public String getColumnKey() {
            return columnKey;
        }

        public void setColumnKey(String columnKey) {
            this.columnKey = columnKey;
        }

        public String getExtra() {
            return extra;
        }

        public void setExtra(String extra) {
            this.extra = extra;
        }
    }

    /**
     * 獲取表結構資訊
     * 目前僅支援mysql
     */
    private static List<TableInfo> getTableInfo() {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        ArrayList<TableInfo> list = new ArrayList<>();
        try {
            conn = DBConnectionUtil.getConnection();

            //表欄位資訊
            String sql = "select column_name,data_type,column_comment,column_key,extra from information_schema.columns where table_schema = (select database()) and table_name=?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, tableName);
            rs = ps.executeQuery();
            while (rs.next()) {
                TableInfo tableInfo = new TableInfo();
                //列名,全部轉為小寫
                tableInfo.setColumnName(rs.getString("column_name").toLowerCase());
                //列型別
                tableInfo.setDataType(rs.getString("data_type"));
                //列註釋
                tableInfo.setColumnComment(rs.getString("column_comment"));
                //主鍵
                tableInfo.setColumnKey(rs.getString("column_key"));
                //主鍵型別
                tableInfo.setExtra(rs.getString("extra"));
                list.add(tableInfo);
            }

            //表註釋
            sql = "select table_comment from information_schema.tables where table_schema = (select database()) and table_name=?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, tableName);
            rs = ps.executeQuery();
            while (rs.next()) {
                //表註釋
                tableComment = rs.getString("table_comment");
            }
        } catch (SQLException e) {

            e.printStackTrace();
        } finally {
            if(rs != null){
                DBConnectionUtil.close(conn, ps, rs);
            }
        }
        return list;
    }

    public static void main(String[] args) {
//        createWord();
//        createExcel();
//        autoGenerator("tb_user");
    }
}
View Code

 

  後記

  通過FreeMarker,按照固定格式,快速生成Word、Excel文件,或者生成程式碼,簡單高效。

  生成文件,資料來源可能是直接讀庫獲取,也有可能是要使用者在頁面上填寫,再傳入後臺,這時候就可以將我們的模板檔案,另存為html格式,小調整之後就可以展示給使用者,最大程度保證了使用者看到的文件頁面跟生成、匯出的文件格式是一致的。

相關文章