【Java/JDBC】借助ResultSetMetaData,从数据库表中抽取字段信息存成Excel文件
本例工程下载: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文件的更多相关文章
- 【Java/JDBC】利用ResultSetMetaData从数据库的某表中获取字段信息并存到csv文件
代码下载:https://files.cnblogs.com/files/xiandedanteng/FindNotnullColumns20191102-2.rar 这篇还不够完善,请看更完善的续篇 ...
- c++获取sqlite3数据库表中所有字段的方法
常用方法: 1.使用sqlite3_get_table函数 2.获取sqlite创建表的sql语句字符串,然后进行解析获取到相应的字段 3.采用配置文件的方式,将所有字段名写入配置文件 方法1:使用s ...
- 将文件导入到SQL server数据库表中的字段中
一.在要执行的sql server数据库a中执行如下脚本,创建存储过程sp_textcopy /* 将二进制文件导入.导出到数据库相应字段列中 */ CREATE PROCEDURE sp_textc ...
- oracle 中查看数据库表中某个字段是否重复
1.select 表中重复的字段 from 表名 group by 表中的重复的字段 HAVING count(表中的重复的字段)>1 举例说明 : 表名 : psp_cell_model ...
- 往sql数据库表中添加字段
通用式: alter table [表名] add [字段名] 字段属性 default 缺省值 default 是可选参数增加字段: alter table [表名] add 字段名 smallin ...
- mysql导出数据库表名与字段信息
一.导出数据库表格信息 #mysql导出库的表格信息 SELECT A.TABLE_SCHEMA, A.TABLE_NAME, A.TABLE_ROWS, A.CREATE_TIME, A.TABLE ...
- java如何获得数据库表中各字段的字段名
public class TestDemo { public static Connection getConnection() { Connection conn = null; try { Cla ...
- mysql数据库表中判断字段是否存在,如果不存在则创建该字段
$key_answer = 'answer'.$question_num; $test_question = mysql_query('DESCRIBE question_manage {$key_q ...
- 用dataset做数据源时,让gridview显示的列名与数据库表中的字段名不同
原文发布时间为:2008-10-27 -- 来源于本人的百度文章 [由搬家工具导入] 确定GridView的AutoGenerateColumns设置为False;使用GridView的“编辑列”,添 ...
随机推荐
- win中使用curl上传文件报错
今天晚上复现“WordPress插件Easy WP SMTP反序列化漏洞”时,需要使用curl上传文件,我又用的windows环境,一直出错 curl: (26) couldn't open file ...
- jvm系列(十):如何优化Java GC「
转自:https://www.cnblogs.com/ityouknow/p/7653129.html 本文由CrowHawk翻译,地址:如何优化Java GC「译」,是Java GC调优的经典佳作. ...
- SAP官方提供的人脸识别API
https://api.sap.com/api/face_detection_api/resource 准备一张克里斯蒂亚诺 - 罗纳尔多的图片: 点击Choose File按钮,加载这些图片,然后点 ...
- 如何对SAP Leonardo上的机器学习模型进行重新训练
Jerry之前的两篇文章介绍了如何通过Restful API的方式,消费SAP Leonardo上预先训练好的机器学习模型: 如何在Web应用里消费SAP Leonardo的机器学习API 部署在SA ...
- 分布式爬虫-bilibili评论
实属课程需要,不然早就放弃在半路了.维持了断续半个多月的 bug 调试,突然就实现了.很是欣慰.网上关于分布式爬虫的都是一些介绍,实战的不多并且都很相似,说的云来雾去的,只是项目的流程.可能是项目一路 ...
- python 爬虫抓取 MOOC 中国课程的讨论区内容
一:selenium 库 selenium 每次模拟浏览器打开页面,xpath 匹配需要抓取的内容.可以,但是特别慢,相当慢.作为一个对技术有追求的爬虫菜鸡,狂补了一些爬虫知识.甚至看了 scrapy ...
- Echarts如何添加鼠标点击事件?防止重复触发点击事件
Echarts如何添加鼠标点击事件? 1.通常我们只使用了以下代码,通过配置项和数据显示图表. var myChart = echarts.init(document.getElementById(' ...
- (转载)小白的linux设备驱动归纳总结(一):内核的相关基础概念---学习总结
1. 学习总结 小白的博客讲的linux内核驱动这一块的东西比较基础,因此想通过学习他的博客,搭配着看书的方式来学习linux内核和驱动.我会依次更新在学习小白的博客的过程的感悟和体会. 2.1 内核 ...
- 熟记这些python内置函数,你离大佬就不远了
python内置了很多函数,方便我们在写程序的时候调用,在ython 2.7 的所有内置函数共有80个.熟练记住和使用这些内置函数,将大大提高写Python代码的速度和代码的优雅程度. 以下代码示例用 ...
- nginx负载均衡简单实例
nginx分配服务器策略 1.轮询(默认) 每一个请求按时间顺序逐一分配到不同的祸端服务器,如果后端服务器 down 掉,能自动抵触 2.weight(权重) weight代表权重,默认为1,权重越高 ...