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();
        }
    }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Coder_Qiang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值