【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的“编辑列”,添 ...
随机推荐
- fiddle--APP弱网测试
一.安装Fiddler 网上说要先安装.NET Framwork4,应该是由于本机已装,所以在安装Fiddler时并没有相关提示. Fiddler安装包:https://www.telerik.com ...
- 完整的ELK+filebeat+kafka笔记
之前有写过elasticsearch集群和elk集群的博客, 都是基于docker的,使用docker-compose进行编排(K8S暂未掌握) 三台服务器搭建es集群:https://www.cnb ...
- Tensorflow ARM交叉编译错误集锦
版权声明:本文为博主(Jimchen)原创文章,未经博主允许不得转载. ttps://www.cnblogs.com/jimchen1218/p/11611975.html 前言: Tensorflo ...
- Django:总结setting中的配置
一.Django setting配置说明 二.setting配置一览 一.Django setting配置说明 1.基础 DJANGO_SETTING_MODULE环境变量:让settings模块被包 ...
- 【枚举】【lrj黑书】奇怪的问题(古老的智力题)
题目描述: 请回答下面的 10 个问题,你的回答应保证每题惟有你的选择是正确的. ⑴ 第一个答案是b 的问题是哪一个?(a )2 ( b ) 3 ( c ) 4 ( d ) 5 ( e ) 6⑵ 恰好 ...
- Apache Maven setting.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to the Apache Soft ...
- 日志分析方法概述 & Web日志挖掘分析的方法
日志在计算机系统中是一个非常广泛的概念,任何程序都有可能输出日志:操作系统内核.各种应用服务器等等.日志的内容.规模和用途也各不相同,很难一概而论. 本文讨论的日志处理方法中的日志,仅指Web日志.其 ...
- .NET 推荐博客
燎原之星的博客 农码一生博文索引 http://www.cnblogs.com/zhaopei/p/Indexes.html 那些年搞不懂的术语.概念:协变.逆变.不变体 http://www.cnb ...
- [唐胡璐]Selenium技巧 - 定制元素属性检查,并写到ReportNG中
QTP 和Selenium 都会有这种要检查某一个控件元素属性的情况,比如去检查一个Button的显示文字是什么? 为了更方便的书写程序,并优美的显示到HTML测试报告中,做了以下几个小小的封装,只是 ...
- 洛谷P1330 封锁阳光大学【dfs】
题目:https://www.luogu.org/problemnew/show/P1330 题意:一个无向边,一个河蟹可以占领一个点,但一个点只能被一个河蟹占领. 占领了一个点之后,这个点所有的边都 ...