java 通过FreeMarker导出数据库结构word文档详解编程语言

一般所有的项目都需要数据库设计文档,对于表不多的可以编辑word文档,自己写,但对于表很多,字段很多的数据库,这时候写设计文档就很麻烦,楼主就是遇到这个问题,项目70张表,一个个写到文档里是在麻烦,所以就像有没有可以通过程序生成。

image

具体思路

  • 通过jdbc获取所有的表名
  • 然后获取所有表的字段描述
  • 通过FreeMarker模版文件来生成word

注:首先通过jdbc连接你要生成word文档的数据库,怎么连接网上都有,这个不在这里多介绍。

通过jdbc获取所有的表名

  • 可以使用
show tables

这个方法获取到库下所有的表,但是有时候可能需要表的注释,那就用另外一条语句

select table_name,table_comment from information_schema.tables where table_schema = 'TABLE_ACHEMA' //TABLE_ACHEMA就是数据库名

这里就直接使用executeQuery()方法就行:

        result = stmt.executeQuery("select table_name,table_comment from information_schema.tables where table_schema = 'pension_service'");  
        while (result.next()){ 
                String name = result.getString(1);//表名 
                String comment = result.getString(2);//表注释 
                Table table=new Table(); 
                table.setName(name); 
                table.setComment(comment); 
            tables.add(table); 
        }

获取到后可以放到自己写的一个实体类,作为FreeMarker模版文件的数据源

通过jdbc获取所有的表的字段

方法和上面一样
SQL:

select ORDINAL_POSITION,COLUMN_NAME,COLUMN_TYPE,EXTRA,COLUMN_COMMENT from information_schema.columns where table_schema ='TABLE_ACHEMA' and table_name = 'TABLE_NAME' "//TABLE_ACHEMA就是数据库名  TABLE_NAME表明表名 
 
// ORDINAL_POSITION:列标识号。 
// COLUMN_NAME:列名(字段名称)。 
// COLUMN_TYPE:数据类型。 
// EXTRA:额外信息(例如:auto_increment) 
// COLUMN_NAME:列名(字段名称)。 
// COLUMN_COMMENT:列注释

information_schema.columns 里存放了所有的字段的信息,这边可以自己自定义取哪些信息.

通过FreeMarker模版文件来生成word

首先要有自己的模版

Word 文档模板:普通的doc、docx都是二进制文件,操作起来比较麻烦,那么我们可以采用变通的方式,用word 的xml格式。

可以自己先在文档里做一个自己想要的表样式 例如:
image
然后另存为,选择xml格式
image
然后打开之后看一下,
image

不要被这么多代码恐吓到,仔细观察就可以找到word里的表格在xml怎么表示了,找到之后就可以生成我们所需要的模版文件,加上

 <#list tables as table>//表循环 
 ... 
 <#list table.columns as col>//表字段循环 
... 
</#list> 
.. 
 </#list> 

在这边上传一个我这边用的模版供大家参考:
link

有了模版就可以直接生成文档了:代码:

public class WordHandler { 
    private Configuration configuration = null; 
 
    public WordHandler() { 
        configuration = new Configuration(); 
        configuration.setDefaultEncoding("UTF-8"); 
    } 
 
    public void data2word( Map<String,Object> data) { 
        // 设置模本装置方法和路径,FreeMarker支持多种模板装载方法。可以servlet,classpath,数据库装载, 
        // 这里我们的模板是放在org.cnzjw.template包下面 
        configuration.setClassForTemplateLoading(this.getClass(), 
                "/"); 
        Template t = null; 
        try { 
            // word.ftl为要装载的模板 
            t = configuration.getTemplate("table.ftl"); 
        } catch (IOException e) { 
            e.printStackTrace(); 
        } 
        // 输出文档路径及名称 
        File outFile = new File("/Users/gengqiang/Desktop/table.doc"); 
        Writer out = null; 
        try { 
            out = new BufferedWriter(new OutputStreamWriter( 
                    new FileOutputStream(outFile))); 
        } catch (FileNotFoundException e1) { 
            e1.printStackTrace(); 
        } 
 
        try { 
            t.process(data, out); 
        } catch (TemplateException e) { 
            e.printStackTrace(); 
        } catch (IOException e) { 
            e.printStackTrace(); 
        } 
    } 
    @Test 
    public  void test() throws Exception { 
        WordHandler wh = new WordHandler(); 
        List<Table> tables=TableHandler.getTables();//获取表结构数据 
        Map<String,Object> data=new HashMap<String,Object>(); 
        data.put("tables",tables); 
        wh.data2word(data); 
    } 
 
}

2个实体类:

package com.coderqiang.tabledoc.entity; 
 
/** 
 * Created by gengqiang on 2017/6/27. 
 */ 
public class Column { 
    private Integer index; 
    private String name; 
    private String dataType; 
    private String  constraint; 
    private String comment; 
 
    public Integer getIndex() { 
        return index; 
    } 
 
    public void setIndex(Integer index) { 
        this.index = index; 
    } 
 
    public String getName() { 
        return name; 
    } 
 
    public void setName(String name) { 
        this.name = name; 
    } 
 
    public String getDataType() { 
        return dataType; 
    } 
 
    public void setDataType(String dataType) { 
        this.dataType = dataType; 
    } 
 
 
    public String getConstraint() { 
        return constraint; 
    } 
 
    public void setConstraint(String constraint) { 
        this.constraint = constraint; 
    } 
 
    public String getComment() { 
        return comment; 
    } 
 
    public void setComment(String comment) { 
        this.comment = comment; 
    } 
 
    @Override 
    public String toString() { 
        return "Column{" + 
                "index=" + index + 
                ", name='" + name + '/'' + 
                ", dataType='" + dataType + '/'' + 
                ", constraint='" + constraint + '/'' + 
                ", comment='" + comment + '/'' + 
                '}'; 
    } 
} 
 
 
package com.coderqiang.tabledoc.entity; 
 
import java.util.List; 
 
/** 
 * Created by gengqiang on 2017/6/27. 
 */ 
public class Table { 
    private String name; 
    private String comment; 
    private List<Column> columns; 
 
    public String getName() { 
        return name; 
    } 
 
    public void setName(String name) { 
        this.name = name; 
    } 
 
    public String getComment() { 
        return comment; 
    } 
 
    public void setComment(String comment) { 
        this.comment = comment; 
    } 
 
    public List<Column> getColumns() { 
        return columns; 
    } 
 
    public void setColumns(List<Column> columns) { 
        this.columns = columns; 
    } 
 
    @Override 
    public String toString() { 
        return "Table{" + 
                "name='" + name + '/'' + 
                ", comment='" + comment + '/'' + 
                ", columns=" + columns + 
                '}'; 
    } 
} 

获取表结构数据:

package com.coderqiang.tabledoc.service; 
 
 
import com.coderqiang.tabledoc.entity.Column; 
import com.coderqiang.tabledoc.entity.Table; 
import org.junit.Test; 
 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.ResultSet; 
import java.sql.Statement; 
import java.util.ArrayList; 
import java.util.List; 
 
/** 
 * Created by gengqiang on 2017/6/27. 
 */ 
public class TableHandler { 
 
    /** 
     * @param args 
     */ 
    //驱动程序就是之前在classpath中配置的JDBC的驱动程序的JAR 包中 
    public static final String DBDRIVER = "com.mysql.jdbc.Driver"; 
    //连接地址是由各个数据库生产商单独提供的,所以需要单独记住 
    public static final String DBURL = "jdbc:mysql://localhost:3306/pension_service"; 
    //连接数据库的用户名 
    public static final String DBUSER = "****"; 
    //连接数据库的密码 
    public static final String DBPASS = "****"; 
 
    public static List<String> getTableNames() throws Exception 
    { 
        List<String> tableNames=new ArrayList<String>(); 
        Connection con = null; //表示数据库的连接对象 
        Statement stmt = null;  //表示数据库的更新操作 
        ResultSet result = null; //表示接收数据库的查询结果 
        Class.forName(DBDRIVER); //1、使用CLASS 类加载驱动程序 
        con = DriverManager.getConnection(DBURL,DBUSER,DBPASS); //2、连接数据库 
        stmt = con.createStatement(); //3、Statement 接口需要通过Connection 接口进行实例化操作 
        result = stmt.executeQuery("show tables"); //执行SQL 语句,查询数据库 
        while (result.next()){ 
            String name = result.getString(1); 
            tableNames.add(name); 
        } 
        result.close(); 
        con.close(); // 4、关闭数据库 
        return tableNames; 
    } 
 
 
    public static List<Table> getTables() throws Exception 
    { 
        List<Table> tables=new ArrayList<Table>(); 
        Connection con = null; //表示数据库的连接对象 
        Statement stmt = null;  //表示数据库的更新操作 
        ResultSet result = null; //表示接收数据库的查询结果 
        Class.forName(DBDRIVER); //1、使用CLASS 类加载驱动程序 
        con = DriverManager.getConnection(DBURL,DBUSER,DBPASS); //2、连接数据库 
        stmt = con.createStatement(); //3、Statement 接口需要通过Connection 接口进行实例化操作 
        result = stmt.executeQuery("select table_name,table_comment from information_schema.tables where table_schema = 'pension_service' /n"); //执行SQL 语句,查询数据库 
        while (result.next()){ 
                String name = result.getString(1); 
                String comment = result.getString(2); 
                Table table=new Table(); 
                table.setName(name); 
                table.setComment(comment); 
            tables.add(table); 
        } 
        for(Table table:tables) 
        { 
            List<Column>columns=new ArrayList<Column>(); 
            //查询字段 
            result = stmt.executeQuery("select ORDINAL_POSITION,COLUMN_NAME,COLUMN_TYPE,EXTRA,COLUMN_COMMENT from information_schema.columns where table_schema ='pension_service' and table_name = '"+table.getName()+"' "); //执行SQL 语句,查询数据库 
            while (result.next()){ 
                int index = result.getInt(1); 
                String name = result.getString(2); 
                String type = result.getString(3); 
                String constraint = result.getString(4); 
                String comment = result.getString(5); 
                Column column=new Column(); 
                column.setIndex(index); 
                column.setName(name); 
                column.setDataType(type); 
                column.setConstraint(constraint); 
                column.setComment(comment); 
                columns.add(column); 
            } 
            table.setColumns(columns); 
        } 
        result.close(); 
        con.close(); // 4、关闭数据库 
        return tables; 
    } 
 
    @Test 
    public void test() 
    { 
        try { 
            TableHandler.getTables(); 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
    } 
} 

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/13829.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论