本例工程下载:https://files.cnblogs.com/files/xiandedanteng/FindNotnullColumns20191102-3.rar

工作中曾有个为42张表建立测试文件的任务,文件里是表的必填字段及两三条记录,sheetname是表名,事虽简单,但架不住量多,干的我是肩酸手疼。

后来一想,用ResultSetMetaData不就可以一次性完成任务了吗,于是有了下面的类:

package com.hy;

import java.io.FileOutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

class Field{
    String name;    // 列名
    int size;        // 列容量
    String type;    // 列数据类型
    boolean allowNull;// 列是否允許为空
}

/**
 * 从数据库表中抽取字段信息存成Excel文件
 * @author horn1
 *
 */
public class XlsMaker {
    private static Logger log = Logger.getLogger(XlsMaker.class);

    // 连接到数据库的四大属性
    private static final String DRIVER = "com.mysql.jdbc.Driver";
    private static final String DBURL = "jdbc:mysql://192.168.161.130:3306/test?useUnicode=true&characterEncoding=utf-8";
    private static final String USER = "root";
    private static final String PSWD = "12345678";

    /**
     * 从表数组里取出表,从表里取出字段信息,每个表做成一个xls文件
     *
     * @param tables
     */
    public void makeXlsFrom(String[] tables) {
        final String exportPath="d:\\";
        Connection conn = null;
        Statement stmt = null;

        try {
            Class.forName(DRIVER).newInstance();
            conn = DriverManager.getConnection(DBURL, USER, PSWD);
            stmt = conn.createStatement();

            for(String table:tables) {
                List<Field> fields=fetchTableFields(conn,stmt,table,true);
                String xlsFilename=exportPath+table+getTimestamp()+".xls";

                writeFile(table,fields,xlsFilename);
            }
        } catch (Exception e) {
            System.out.print(e.getMessage());
        } finally {
            try {
                stmt.close();
                conn.close();
            } catch (SQLException e) {
                System.out.print("Can't close stmt/conn because of " + e.getMessage());
            }
        }
    }

    /**
     * 将表,字段信息写入文件xlsFilename
     * @param table
     * @param fields
     * @param xlsFilename
     * @throws Exception
     */
    private void writeFile(String table,List<Field> fields,String xlsFilename) throws Exception{
        // 得到四行
        List<String> allownulls=new ArrayList<String>();
        List<String> types=new ArrayList<String>();
        List<String> sizes=new ArrayList<String>();
        List<String> names=new ArrayList<String>();

        for(Field f:fields) {
            allownulls.add(String.valueOf(f.allowNull));
            types.add(f.type);
            sizes.add(String.valueOf(f.size));
            names.add(f.name);
        }

        HSSFWorkbook hssfWorkbook = new HSSFWorkbook();// 创建工作簿
        HSSFSheet sheet = hssfWorkbook.createSheet();// 新建Sheet
        hssfWorkbook.setSheetName(0, table);// 设置sheet名

        HSSFRow row = sheet.createRow(0);// 新建一行
        row.createCell(0).setCellValue("Allow null:");// 首个单元格写类型
        for(int i=0;i<allownulls.size();i++) {
            row.createCell(i+1).setCellValue(allownulls.get(i));// 其它写字段信息
        }

        row = sheet.createRow(1);
        row.createCell(0).setCellValue("Type:");
        for(int i=0;i<types.size();i++) {
            row.createCell(i+1).setCellValue(types.get(i));
        }

        row = sheet.createRow(2);
        row.createCell(0).setCellValue("Size:");
        for(int i=0;i<sizes.size();i++) {
            row.createCell(i+1).setCellValue(sizes.get(i));
        }

        row = sheet.createRow(3);
        row.createCell(0).setCellValue("Name:");
        for(int i=0;i<names.size();i++) {
            row.createCell(i+1).setCellValue(names.get(i));
        }

        // 将工作簿写入文件
        FileOutputStream fileOut = new FileOutputStream(xlsFilename);
        hssfWorkbook.write(fileOut);
        hssfWorkbook.close();

        log.info("文件 '"+xlsFilename+"' 写入完了.");
    }

    /**
     * 从表中取字段信息
     * @param conn
     * @param stmt
     * @param table
     * @param isFetchall:此参数为真时取所有字段,为假时取非空字段
     * @return
     * @throws Exception
     */
    private List<Field> fetchTableFields(Connection conn,Statement stmt,String table,boolean isFetchall)  throws Exception{
        List<Field> fields=new ArrayList<Field>();

        String sql = "select * from "+table+"";

        ResultSet rs = stmt.executeQuery(sql);
        ResultSetMetaData rsMetadata = rs.getMetaData();

        int count = rsMetadata.getColumnCount();
        for (int i=0; i<count; i++) {
            int index=i+1;

            String columnName = rsMetadata.getColumnLabel(index);// 列名
            int size =rsMetadata.getColumnDisplaySize(index);// 列容量
            String columnType = rsMetadata.getColumnTypeName(index);// 列数据类型
            boolean allowNull=(rsMetadata.isNullable(index)!=0);// 列是否允許为空

            Field f=new Field();
            f.name=columnName;
            f.size=size;
            f.type=columnType;
            f.allowNull=allowNull;

            if(isFetchall==true) {
                fields.add(f);
            }else {
                if(f.allowNull==false) {
                    fields.add(f);
                }
            }
        }

        rs.close();

        return fields;
    }

    /**
     * 取得当前时间戳
     * @return
     */
    private static String getTimestamp() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        return sdf.format(new Date().getTime());
    }

    /**
     * 执行点
     * @param args
     */
    public static void main(String[] args) {
        String[] tables= {"emp","person","testdb"};
        XlsMaker xm=new XlsMaker();
        xm.makeXlsFrom(tables);
    }
}

输出Xls效果如下:

真正要用的时候,按类型填完数据,删除头三行和第一列就可以用了。

pom.xml有三个依赖项:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.hy</groupId>
      <artifactId>FindNotnullColumns</artifactId>
      <version>0.0.1-SNAPSHOT</version>

      <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>
    </dependencies>
</project>

虽然任务过去,工具才做出来,但有了工具总比没有好,说不定下次就能省事,要是这个工具也能帮到你那就再好不过了。

--END-- 2019年11月2日20:01:28

【Java/JDBC】借助ResultSetMetaData,从数据库表中抽取字段信息存成Excel文件的更多相关文章

  1. 【Java/JDBC】利用ResultSetMetaData从数据库的某表中获取字段信息并存到csv文件

    代码下载:https://files.cnblogs.com/files/xiandedanteng/FindNotnullColumns20191102-2.rar 这篇还不够完善,请看更完善的续篇 ...

  2. c++获取sqlite3数据库表中所有字段的方法

    常用方法: 1.使用sqlite3_get_table函数 2.获取sqlite创建表的sql语句字符串,然后进行解析获取到相应的字段 3.采用配置文件的方式,将所有字段名写入配置文件 方法1:使用s ...

  3. 将文件导入到SQL server数据库表中的字段中

    一.在要执行的sql server数据库a中执行如下脚本,创建存储过程sp_textcopy /* 将二进制文件导入.导出到数据库相应字段列中 */ CREATE PROCEDURE sp_textc ...

  4. oracle 中查看数据库表中某个字段是否重复

    1.select  表中重复的字段 from  表名 group by 表中的重复的字段 HAVING count(表中的重复的字段)>1 举例说明 : 表名 : psp_cell_model  ...

  5. 往sql数据库表中添加字段

    通用式: alter table [表名] add [字段名] 字段属性 default 缺省值 default 是可选参数增加字段: alter table [表名] add 字段名 smallin ...

  6. mysql导出数据库表名与字段信息

    一.导出数据库表格信息 #mysql导出库的表格信息 SELECT A.TABLE_SCHEMA, A.TABLE_NAME, A.TABLE_ROWS, A.CREATE_TIME, A.TABLE ...

  7. java如何获得数据库表中各字段的字段名

    public class TestDemo { public static Connection getConnection() { Connection conn = null; try { Cla ...

  8. mysql数据库表中判断字段是否存在,如果不存在则创建该字段

    $key_answer = 'answer'.$question_num; $test_question = mysql_query('DESCRIBE question_manage {$key_q ...

  9. 用dataset做数据源时,让gridview显示的列名与数据库表中的字段名不同

    原文发布时间为:2008-10-27 -- 来源于本人的百度文章 [由搬家工具导入] 确定GridView的AutoGenerateColumns设置为False;使用GridView的“编辑列”,添 ...

随机推荐

  1. 页面中的div居中

    div的居中 一.页面的水平居中 #article{ position: relative; margin: 0 auto; width: 80%; background-color: aquamar ...

  2. golang的序列化与反序列化的几种方式

    golang用来序列化的模块有很多,我们来介绍3个. json 首先登场的是json,这个几乎毋庸置疑. 序列化 package main import ( "encoding/json&q ...

  3. 哲学家就餐问题 C语言实现

    场景: 原版的故事里有五个哲学家(不过我们写的程序可以有N个哲学家),这些哲学家们只做两件事--思考和吃饭,他们思考的时候不需要任何共享资源,但是吃饭的时候就必须使用餐具,而餐桌上的餐具是有限的,原版 ...

  4. ubuntu安装supervisor

    1. Ubuntu14中supervisor的安装及配置 2. Ubuntu 14.04下进程管理工具supervisor安装 3. Supervisor使用教程 4. supervisor在deep ...

  5. K8S漏洞报告 | 近期bug fix解读&1.13主要bug fix汇总

    K8s近期漏洞详解 Kubernetes仪表盘漏洞(CVE-2018-18264) 因为这一漏洞,用户可以“跳过”登录过程获得仪表盘所使用的自定义TLS证书.如果您已将Kubernetes仪表盘配置为 ...

  6. 理解 shared_ptr实现copy-on-write(COW)

    看muduo库某个生产者消费者的地方,利用shared_ptr有效减少了锁的范围及无用的拷贝,下面来看一看 // reader 消费者, shared_ptr<map<string,int ...

  7. jQuery——jQuery对象与DOM对象

    1.jQuery对象与DOM对象的区别 通过jQuery方法包装后的对象,是一个类数组对象.它与DOM对象完全不同,唯一相似的是它们都能操作DOM. 通过jQuery处理DOM的操作,可以让开发者更专 ...

  8. JAVA遇见HTML——JSP篇:JSP内置对象(下)

    什么是session session表示客户端与服务器的一次会话 Web中的session指的是用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间 从上述 ...

  9. IntelliJ IDEA 生成类注释和方法注释

    1.类注释 settings-> file and code templates-> files(Class) 代码: #if (${PACKAGE_NAME} && ${ ...

  10. Spring框架集成FreeMarker

    一.Spring in Action (转自:http://blog.163.com/zhang-_-jie/blog/static/16178437820105821120822/ ) FreeMa ...