背景:在工作中可能需要将表结构以表格的形式写到详细设计文档中,当表的个数很多的时候在文档中编写表结构的表格可能会耗费一段时间,以下是将数据库中某些表结构以表格的形式批量的写到一个文档中。文档中格式如下

北向-三方信息表

north_third_party_info


字段名

类型

长度

是否必须

字段注释

ID

BIGINT

19


主键ID

THIRD_PARTY_NAME

VARCHAR

64


第三方名称

THIRD_PARTY_UID

VARCHAR

32


第三方唯一标识

MEMO

VARCHAR

256


备注

CREATE_USER

BIGINT

19


创建人

CREATE_TIME

DATETIME

19


创建时间

UPDATE_USER

BIGINT

19


更新人

UPDATE_TIME

DATETIME

19


更新时间

1、准备表

将表结构在mysql中运行,生成north_third_party_info表

-- ------------
-- Table structure for `north_third_party_info`
-- ------------
DROP TABLE IF EXISTS `north_third_party_info`;
CREATE TABLE `north_third_party_info` (
  `ID` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `THIRD_PARTY_NAME` varchar(64) NOT NULL COMMENT '第三方名称',
  `THIRD_PARTY_UID` varchar(32) NOT NULL COMMENT '第三方唯一标识',
  `MEMO` varchar(256) DEFAULT NULL COMMENT '备注',
  `CREATE_USER` bigint(20) DEFAULT NULL COMMENT '创建人',
  `CREATE_TIME` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `UPDATE_USER` bigint(20) DEFAULT NULL COMMENT '更新人',
  `UPDATE_TIME` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`ID`),
  KEY `IDX_CREATE_USER` (`CREATE_USER`) USING BTREE,
  KEY `IDX_UPDATE_USER` (`UPDATE_USER`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='北向-三方信息表';

2、代码读取

import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import java.io.FileOutputStream;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class JdbcUtil {
    //获得驱动
    private static String DRIVER = "org.mariadb.jdbc.Driver";
    //获得url  
    private static String URL = "jdbc:mariadb://127.0.0.1:3306/user?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8";
    //获得连接数据库的用户名  
    private static String USER = "mysql";
    //获得连接数据库的密码  
    private static String PASS = "123456";


    //需要生成的表结构
    private static String[] TABLE_NAMES = {"north_third_party_info"};

    private static String OUTPUT_PATH = "C:\\Users\\wsl\\Desktop\\tables.doc";

    private static String[] HEADER = {"字段名", "类型", "长度", "是否必须", "字段注释"};
      static {
        try {
            //初始化JDBC驱动并让驱动加载到jvm中  
            Class.forName(DRIVER);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() {
        Connection conn = null;
        try {
            //连接数据库  
         
        /*
         * 设置可获取REMARK备注信息
        Properties props =new Properties();
        props.put("remarksReporting","true");
        props.put("user", USER);
        props.put("password", PASS);
        conn =DriverManager.getConnection(URL,props);*/

            conn = DriverManager.getConnection(URL, USER, PASS);
            conn.setAutoCommit(true);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    //关闭连接
    public static void close(Object o) {
        if (o == null) {
            return;
        }
        if (o instanceof ResultSet) {
            try {
                ((ResultSet) o).close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } else if (o instanceof Statement) {
            try {
                ((Statement) o).close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } else if (o instanceof Connection) {
            Connection c = (Connection) o;
            try {
                if (!c.isClosed()) {
                    c.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


    public static void close(ResultSet rs, Statement stmt,
                             Connection conn) {
        close(rs);
        close(stmt);
        close(conn);
    }

    public static void close(ResultSet rs,
                             Connection conn) {
        close(rs);
        close(conn);
    }
       /**
     * @throws
     * @Description: 获取表中列值信息
     * @author: chenzw
     * @CreateTime: 2014-1-27 下午2:55:56
     */
    public static List<String[]> printColumnsInfo(String tableName) {
        List<String[]> res = new ArrayList<>();
        Connection conn = getConnection();
        ResultSet rs = null;

        try {
            /**
             * 设置连接属性,使得可获取到列的REMARK(备注)
             */
//   ((OracleConnection)conn).setRemarksReporting(true);
            DatabaseMetaData dbmd = conn.getMetaData();
            /**
             * 获取可在指定类别中使用的表列的描述。
             * 方法原型:ResultSet getColumns(String catalog,String schemaPattern,String tableNamePattern,String columnNamePattern)
             * catalog - 表所在的类别名称;""表示获取没有类别的列,null表示获取所有类别的列。
             * schema - 表所在的模式名称(oracle中对应于Tablespace);""表示获取没有模式的列,null标识获取所有模式的列; 可包含单字符通配符("_"),或多字符通配符("%");
             * tableNamePattern - 表名称;可包含单字符通配符("_"),或多字符通配符("%");
             * columnNamePattern - 列名称; ""表示获取列名为""的列(当然获取不到);null表示获取所有的列;可包含单字符通配符("_"),或多字符通配符("%");
             */
            rs = dbmd.getTables(null, null, tableName, new String[]{"TABLE", "VIEW"});

            //创建表格
            rs.next();
            res.add(new String[]{rs.getString("REMARKS"), tableName});

            rs = dbmd.getColumns(null, null, tableName, null);

            while (rs.next()) {
                String columnName = rs.getString("COLUMN_NAME");  //列名
                String dataTypeName = rs.getString("TYPE_NAME");  //java.sql.Types类型名称(列类型名称)
                String columnSize = String.valueOf(rs.getInt("COLUMN_SIZE"));  //列大小
                /**
                 *  0 (columnNoNulls) - 该列不允许为空
                 *  1 (columnNullable) - 该列允许为空
                 *  2 (columnNullableUnknown) - 不确定该列是否为空
                 */
                String nullAble = rs.getInt("NULLABLE") == 1 ? "否" : "是";  //是否允许为null
                String remarks = rs.getString("REMARKS");  //列描述
                res.add(new String[]{columnName, dataTypeName, columnSize, nullAble, remarks});
                  public static void writeTable(XWPFDocument document, List<String[]> datas) {
        XWPFTable table = document.createTable(datas.size() + 1, 5);
        mergeCellsHorizontal(table, 0, 1, 4);

        //第一行
        XWPFTableRow row0 = table.getRow(0);
        XWPFTableCell cell00 = row0.getCell(0);
        cell00.setText(datas.get(0)[0]);
        cell00.getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);
        cell00.getCTTc().getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);

        XWPFTableCell cell01 = row0.getCell(1);
        cell01.setText(datas.get(0)[1]);
        cell01.getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);
        cell01.getCTTc().getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);


        //第二行,表头
        XWPFTableRow row1 = table.getRow(1);
        for (int i = 0; i < HEADER.length; i++) {
            XWPFTableCell cell = row1.getCell(i);
            cell.setText(HEADER[i]);
            cell.getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);
            cell.getCTTc().getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
        }

        //数据行
        for (int i = 1; i < datas.size(); i++) {
            XWPFTableRow row = table.getRow(i + 1);
            String[] data = datas.get(i);
            for (int j = 0; j < data.length; j++) {
                XWPFTableCell cell = row.getCell(j);
                cell.setText(data[j]);
                cell.getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);
                cell.getCTTc().getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
            }
        }
        // 添加标题
        XWPFParagraph titleParagraph = document.createParagraph();
        // 设置段落居中
        titleParagraph.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun titleRun = titleParagraph.createRun();
        titleRun.setText("分割");
        titleRun.setFontSize(20);
        titleRun.setFontFamily("宋体");
        titleRun.setBold(true);
    }
  /**
     * @Description: 跨列合并
     * table要合并单元格的表格
     * row要合并哪一行的单元格
     * fromCell开始合并的单元格
     * toCell合并到哪一个单元格
     */
    public static void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
        for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
            XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
            if ( cellIndex == fromCell ) {
                // The first merged cell is set with RESTART merge value
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
            } else {
                // Cells which join (merge) the first one, are set with CONTINUE
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
            }
        }
    }


    public static void main(String[] args) throws Exception {
        System.out.println("开始获取表的信息......");
        XWPFDocument document = new XWPFDocument();
        for (String tableName : TABLE_NAMES) {
            writeTable(document, printColumnsInfo(tableName)); //获取表中列值信息
        }
        document.write(new FileOutputStream(OUTPUT_PATH));
        System.out.println("获取表信息成功......");
    }
}

说明,需要修改连接数据库的url(URL),用户名(USER),密码(PASS),需要生成表格的表名(TABLE_NAMES),文档输出的目录(OUTPUT_PATH)

3、效果

北向-三方信息表

north_third_party_info

字段名

类型

长度

是否必须

字段注释

ID

BIGINT

19


主键ID

THIRD_PARTY_NAME

VARCHAR

64


第三方名称

THIRD_PARTY_UID

VARCHAR

32


第三方唯一标识

MEMO

VARCHAR

256


备注

CREATE_USER

BIGINT

19


创建人

CREATE_TIME

DATETIME

19


创建时间

UPDATE_USER

BIGINT

19


更新人