导出数据库表结构到文档中

导出效果:

完整代码:

Controller层:

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Api(value = "TestController",description="TestController")
@RestController
@RequestMapping("/test")
public class TestController {@Autowiredprivate IMetadataService metadataService;@IgnoreSecurity@ApiOperation(value = "DDL2WordTable")@GetMapping(value = "/DDL2WordTable")public void DDL2WordTable(HttpServletRequest request, HttpServletResponse response){try {this.metadataService.DDL2WordTable( response );}catch ( Exception e ){e.printStackTrace();}}
}

service 层:

IMetadataService.java:
import javax.servlet.http.HttpServletResponse;
import java.util.List;public interface IMetadataService {void DDL2WordTable(HttpServletResponse response);List<MySqlTableInfo> collectTableInfos();
}
MetadataServiceImpl.java:
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;@Service
@Slf4j
public class MetadataServiceImpl implements IMetadataService {@Autowiredprivate MetadataMapper metadataMapper;@Value( "${spring.datasource.url}" )private String url;@Overridepublic void DDL2WordTable(HttpServletResponse response) {try {List<MySqlTableInfo> tableInfos = this.collectTableInfos();if( tableInfos == null || tableInfos.size() == 0 ){return;}for( MySqlTableInfo tableInfo:tableInfos ){System.out.println( tableInfo.getTableName() + "  " + tableInfo.getFieldInfos().size() );}response.setContentType("application/msword");String filename = URLEncoder.encode( "xxxx数据库表结构.docx","UTF-8" );response.setHeader("Content-Disposition", "attachment; filename=" + filename);POIWordUtils.writeMysqlTables2Word( tableInfos,response.getOutputStream() );}catch ( Exception e ){e.printStackTrace();}}@Overridepublic List<MySqlTableInfo> collectTableInfos() {List<String> tableNames = this.metadataMapper.showTableNames();if( tableNames == null || tableNames.size() == 0 ){return null;}// todo 从 jdbc url 中提取???String databaseName = "xxxxxxxxxxxxxx";List<MySqlTableInfo> tableInfos = new ArrayList<>();for( String tableName:tableNames ){List<InformationSchemaCOLUMNS> columnsList = this.metadataMapper.queryInformationSchemaCOLUMNS( databaseName,tableName );if( columnsList == null || columnsList.size() == 0 ){continue;}MySqlTableInfo tableInfo = new MySqlTableInfo();List<MySqlTableFieldInfo> fieldInfos = new ArrayList<>();for( InformationSchemaCOLUMNS columns:columnsList ){MySqlTableFieldInfo fieldInfo = new MySqlTableFieldInfo();fieldInfo.setName( columns.getColumnName() );fieldInfo.setType( columns.getDataType() );Long character_maximum_length = columns.getCharacterMaximumLength();if( character_maximum_length != null ){fieldInfo.setLength( character_maximum_length.toString() );}String is_nullable = columns.getIsNullable();if( "YES".equals( is_nullable ) ){fieldInfo.setNullable( true );}else if( "NO".equals( is_nullable ) ){fieldInfo.setNullable( false );}fieldInfo.setComment( columns.getColumnComment() );String column_key = columns.getColumnKey();if( "PRI".equals( column_key ) ){fieldInfo.setPrimaryKey( true );}else if( "UNI".equals( column_key ) ){// todo 唯一索引fieldInfo.setIndexType( "唯一索引" );}else if( "MUL".equals( column_key ) ){fieldInfo.setIndexType( "普通索引" );}else {// todo 其他索引返回什么}fieldInfo.setDefaultValue( columns.getColumnDefault() );fieldInfos.add( fieldInfo );}tableInfo.setTableName( tableName );tableInfo.setFieldInfos( fieldInfos );tableInfos.add( tableInfo );}// set titlesList<String> titles = new ArrayList<>();titles.add( "字段名称" );titles.add( "类型" );titles.add( "长度" );titles.add( "允许为空" );titles.add( "字段说明" );titles.add( "键" );titles.add( "默认值" );titles.add( "索引类型" );for( MySqlTableInfo tableInfo:tableInfos ){tableInfo.setTitles( titles );}return tableInfos;}
}

Mapper 层:

MetadataMapper.java:
import org.apache.ibatis.annotations.Param;import java.util.List;@DataSource("dataSource")
public interface MetadataMapper extends BaseMapper {List<String> showTableNames();List<InformationSchemaCOLUMNS> queryInformationSchemaCOLUMNS(@Param( "databaseName" ) String databaseName,@Param( "tableName" ) String tableName);
}
MetadataMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.xxx.mapper.MetadataMapper"><select id="showTableNames" resultType="java.lang.String">SHOW TABLES</select><select id="queryInformationSchemaCOLUMNS" resultType="com.xxx.vo.InformationSchemaCOLUMNS">SELECTTABLE_CATALOG AS tableCatalog,TABLE_SCHEMA tableSchema,TABLE_NAME AS tableName,COLUMN_NAME AS columnName,ORDINAL_POSITION AS ordinalPosition,COLUMN_DEFAULT AS columnDefault,IS_NULLABLE AS isNullable,DATA_TYPE AS dataType,CHARACTER_MAXIMUM_LENGTH AS characterMaximumLength,CHARACTER_OCTET_LENGTH AS characterOctetLength,NUMERIC_PRECISION AS numericPrecision,NUMERIC_SCALE AS numericScale,DATETIME_PRECISION AS datetimePrecision,CHARACTER_SET_NAME AS characterSetName,COLLATION_NAME AS collationName,COLUMN_TYPE AS columnType,COLUMN_KEY AS columnKey,EXTRA AS extra,PRIVILEGES AS privileges,COLUMN_COMMENT AS columnComment,GENERATION_EXPRESSION AS generationExpressionFROMinformation_schema.COLUMNSWHEREtable_name = #{tableName}ANDtable_schema = #{databaseName}</select>
</mapper>
用到的 VO 类:InformationSchemaCOLUMNS.java:
import lombok.Getter;
import lombok.Setter;@Getter
@Setter
public class InformationSchemaCOLUMNS {private Long ordinalPosition;/*** 字段长度*/private Long characterMaximumLength;private Long characterOctetLength;private Long numericPrecision;private Long numericScale;private Long datetimePrecision;private String tableCatalog;private String tableSchema;private String tableName;/*** 字段名称,如:username*/private String columnName;/*** 默认值*/private String columnDefault;/*** 字段是否允许空值,'YES'、'NO'*/private String isNullable;/*** 字段的数据类型,如:varchar、datetime ...*/private String dataType;private String characterSetName;private String collationName;private String columnType;/*** 该字段的索引类型( 'PRI':主键索引,'UNI':唯一索引,'MUL':普通索引 )*/private String columnKey;private String extra;private String privileges;/*** 字段的注释*/private String columnComment;private String generationExpression;
}
MySqlTableInfo.java:
import lombok.Getter;
import lombok.Setter;import java.util.List;@Getter
@Setter
public class MySqlTableInfo {private String tableName;private List<String> titles;private List<MySqlTableFieldInfo> fieldInfos;
}
MySqlTableFieldInfo.java:
import lombok.Getter;
import lombok.Setter;@Getter
@Setter
public class MySqlTableFieldInfo {/*** 字段名称,如:username*/private String name;/*** 字段的数据类型*/private String type;/*** 字段长度*/private String length;/*** 字段是否允许空值*/private boolean nullable;/*** 字段的注释*/private String comment;/*** 该字段是否是主键*/private boolean primaryKey;/*** 默认值*/private String defaultValue;private String indexType;
}
POI 工具类:POIWordUtils.java:
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;public class POIWordUtils {public static void writeMysqlTables2Word(List<MySqlTableInfo> tableInfos, OutputStream outputStream){XWPFDocument xwpfDocument = null;try {xwpfDocument = new XWPFDocument();// 创建1行3列的表格for( MySqlTableInfo tableInfo:tableInfos ){appendMysqlTable2Word( xwpfDocument,tableInfo );}xwpfDocument.write( outputStream );}catch ( Exception e ){e.printStackTrace();}finally {if( xwpfDocument != null ){try {xwpfDocument.close();}catch ( Exception e ){e.printStackTrace();}}}}private static void appendMysqlTable2Word(XWPFDocument xwpfDocument, MySqlTableInfo tableInfo) {xwpfDocument.createParagraph().createRun().setText( "" );xwpfDocument.createParagraph().createRun().setText( "" );xwpfDocument.createParagraph().createRun().setText( "" );XWPFRun run = xwpfDocument.createParagraph().createRun();run.setFontSize( 12 );run.setText( tableInfo.getTableName() );List<String> titles = tableInfo.getTitles();List<MySqlTableFieldInfo> fieldInfos = tableInfo.getFieldInfos();int colCount = titles.size();int rowCount = 1 + tableInfo.getFieldInfos().size();XWPFTable table = xwpfDocument.createTable(rowCount,colCount );table.setWidth(10000);// table.setTableAlignment( TableRowAlign.CENTER );XWPFTableRow row_title = table.getRow(0);// 设置标题行for( int colIndex = 0;colIndex<colCount;colIndex++ ){XWPFTableCell cell = row_title.getCell(colIndex);cell.setWidthType( TableWidthType.PCT );cell.setWidth( "12.5%" );String title = titles.get(colIndex);setTextForCell( cell,title );cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);}for( int rowIndex=1;rowIndex<rowCount;rowIndex++ ){XWPFTableRow row = table.getRow(rowIndex);row.setHeight( 500 );MySqlTableFieldInfo fieldInfo = fieldInfos.get(rowIndex - 1);XWPFTableCell cell0 = row.getCell(0);XWPFTableCell cell1 = row.getCell(1);XWPFTableCell cell2 = row.getCell(2);XWPFTableCell cell3 = row.getCell(3);XWPFTableCell cell4 = row.getCell(4);XWPFTableCell cell5 = row.getCell(5);XWPFTableCell cell6 = row.getCell(6);XWPFTableCell cell7 = row.getCell(7);cell0.setWidthType( TableWidthType.PCT );cell1.setWidthType( TableWidthType.PCT );cell2.setWidthType( TableWidthType.PCT );cell3.setWidthType( TableWidthType.PCT );cell4.setWidthType( TableWidthType.PCT );cell5.setWidthType( TableWidthType.PCT );cell6.setWidthType( TableWidthType.PCT );cell7.setWidthType( TableWidthType.PCT );/* cell0.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);cell1.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);cell2.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);cell3.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);cell4.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);cell5.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);cell6.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);cell7.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);*/cell0.setWidth( "12.5%" );cell1.setWidth( "12.5%" );cell2.setWidth( "12.5%" );cell3.setWidth( "12.5%" );cell4.setWidth( "12.5%" );cell5.setWidth( "12.5%" );cell6.setWidth( "12.5%" );cell7.setWidth( "12.5%" );setTextForCell( cell0,fieldInfo.getName() );setTextForCell( cell1,fieldInfo.getType() );String length = fieldInfo.getLength();if( length == null ){setTextForCell( cell2,"" );}else {setTextForCell( cell2,String.valueOf( fieldInfo.getLength() ) );}if( fieldInfo.isNullable() ){setTextForCell( cell3,"YES" );}else {setTextForCell( cell3,"NO" );}setTextForCell( cell4,fieldInfo.getComment() );if( fieldInfo.isPrimaryKey() ){setTextForCell( cell5,"主键" );}setTextForCell( cell6,fieldInfo.getDefaultValue() );setTextForCell( cell7,fieldInfo.getIndexType() );}}private static void setTextForCell(XWPFTableCell cell,String text) {// cell.setText( text );CTTc ctTc = cell.getCTTc();CTP ctP = (ctTc.sizeOfPArray() == 0) ?ctTc.addNewP() : ctTc.getPArray(0);XWPFParagraph paragraph = cell.getParagraph(ctP);XWPFRun run = paragraph.createRun();paragraph.setAlignment( ParagraphAlignment.CENTER );paragraph.setVerticalAlignment( TextAlignment.CENTER );// 即小四run.setFontSize( 12 );run.setText( text );}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/499655.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Stdio Execution failed for task ‘:app:compileDebugKotlin‘ 报错解决

具体报错信息如下&#xff1a; compileDebugJavaWithJavac task (current target is 1.8) and compileDebugKotlin task (current target is 17)jvm target compatibility should be set to the same Java version.很显然&#xff0c;这是一个版本冲突问题&#xff0c;compile…

云上攻防-云服务篇弹性计算服务器云数据库实例元数据控制角色AK控制台接管

知识点: 1、云服务-弹性计算服务器-元数据&SSRF&AK 2、云服务-云数据库-外部连接&权限提升 章节点&#xff1a; 云场景攻防&#xff1a;公有云&#xff0c;私有云&#xff0c;混合云&#xff0c;虚拟化集群&#xff0c;云桌面等 云厂商攻防&#xff1a;阿里云&am…

Tomcat服务部署

1、安装jdk、设置环境变量并测试 第一步&#xff1a;安装jdk 在部署 Tomcat 之前必须安装好 jdk&#xff0c;因为 jdk 是 Tomcat 运行的必要环境。 1. #关闭防火墙 systemctl stop firewalld systemctl disable firewalld setenforce 02. #将安装 Tomcat 所需软件包传到/opt…

90%电商APP已沦落至无人下载,用户主观意愿——是真正实用性价值!

90%电商APP已沦落至无人下载&#xff0c;用户主观意愿——是真正实用性价值&#xff01; 文丨微三云营销总监胡佳东&#xff0c;点击上方“关注”&#xff0c;为你分享市场商业模式电商干货。 - 引言&#xff1a;在互联网发展的大时代下&#xff0c;似乎每个月都有新的APP出现…

Linux Shell脚本练习(一)

一、 Linux下执行Shell脚本的方式&#xff1a; 1、用shell程序执行脚本&#xff1a; a、根据你的shell脚本的类型&#xff0c;选择shell程序&#xff0c;常用的有sh&#xff0c;bash&#xff0c;tcsh等 b、程序的第一行#!/bin/bash里面指明了shell类型的&#xff0c;比如#!/…

Programming Abstractions in C阅读笔记:p306-p307

《Programming Abstractions in C》学习第75天&#xff0c;p306-p307总结&#xff0c;总计2页。 一、技术总结 1.Quicksort algorithm(快速排序) 由法国计算机科学家C.A.R(Charles Antony Richard) Hoare&#xff08;东尼.霍尔&#xff09;在1959年开发(develop), 1961年发表…

Windows下使用C++调用海康威视SDK获取实时视频流进行检测

目录 准备海康威视的SDK官网下载下载后解压 Vs 2022创建项目创建32位的环境 将相关文件复制到工程目录下工程配置海康威视SDK配置包含目录配置库目录将dll文件添加到环境中在附加依赖项添加如下内容 工程配置OpenCV配置工程配置包含目录配置库目录 测试 准备海康威视的SDK 官网…

位段 详解

目录 位段的声明位段的内存分配位段的跨平台问题 位段的声明 位段的声明和结构是类似的&#xff0c;有两个不同&#xff1a; 位段的成员必须是 int、unsigned int 或signed int位段的成员名后边有一个冒号和一个数字 例如&#xff0c;A是一个位段类型&#xff1a; struct A…

程序员的金三银四求职宝典

目录 简介&#xff1a; 1.准备简历&#xff1a; 2.强调技术能力&#xff1a; 3.建立个人品牌&#xff1a; 4.提前准备面试&#xff1a; 5.关注招聘信息渠道&#xff1a; 6.提前与内推&#xff1a; 7.心态调整&#xff1a; 结论&#xff1a; 简介&#xff1a; 金三银四是…

老卫带你学---leetcode刷题(130. 被围绕的区域)

130. 被围绕的区域 问题 给你一个 m x n 的矩阵 board &#xff0c;由若干字符 ‘X’ 和 ‘O’ &#xff0c;找到所有被 ‘X’ 围绕的区域&#xff0c;并将这些区域里所有的 ‘O’ 用 ‘X’ 填充。 示例 1&#xff1a; 输入&#xff1a;board [[“X”,“X”,“X”,“X”]…

基于相位的运动放大:如何检测和放大难以察觉的运动(02/2)

目录 一、说明二、算法三、准备处理四、高斯核五、带通滤波器六、复杂的可操纵金字塔七、最终预处理步骤八、执行处理九、金字塔的倒塌十、可视化结果十一、结论 一、说明 日常物体会产生人眼无法察觉的微妙运动。在视频中&#xff0c;这些运动的幅度小于一个像素&#xff0c;…

2月28日做题总结(C/C++真题)

今天是2月28日&#xff0c;做题第三天。道阻且长&#xff0c;行则将至&#xff1b;行而不辍&#xff0c;则未来可期&#xff01; 第一题 static char a[2]{1,2,3};说法是否正确&#xff1f; A---正确 B---错误 正确答案&#xff1a;B 解析&#xff1a;数组定义时&#xf…

LeetCode——栈和队列(Java)

栈和队列 简介[简单] 232. 用栈实现队列[简单] 225. 用队列实现栈[简单] 20. 有效的括号[简单] 1047. 删除字符串中的所有相邻重复项[中等] 150. 逆波兰表达式求值[困难] 239. 滑动窗口最大值[中等] 347. 前 K 个高频元素 简介 记录一下自己刷题的历程以及代码。写题过程中参考…

通过多进程并发方式(fork)实现服务器

以下内容为视频学习记录。 1、父进程accept后返回的文件描述符为cfd以及用于创建连接的lfd; 调用fork()创建子进程后&#xff0c;子进程继承cfd,lfd&#xff0c;通过该cfd与连接过来的客户端通信,lfd对子进程来说没用&#xff0c;可以直接close(lfd); 对于父进程来说&#x…

【MySQL | 第一篇】undo log、redo log、bin log三者之间的区分?

undo log、redo log、bin log三者之间的区分&#xff1f; 从 产生的时间点、日志内容、用途 三方面展开论述即可 1.undo log——撤销日志 时间点&#xff1a;事务开始之前产生&#xff0c;根据当前版本的数据生成一个undo log&#xff0c;也保存在事务开始之前 作用&#xf…

LeetCode:2867. 统计树中的合法路径数目(筛质数+ DFS Java)

目录 2867. 统计树中的合法路径数目 题目描述&#xff1a; 实现代码与思路&#xff1a; 筛质数 DFS 原理思路&#xff1a; 2867. 统计树中的合法路径数目 题目描述&#xff1a; 给你一棵 n 个节点的无向树&#xff0c;节点编号为 1 到 n 。给你一个整数 n 和一个长度为 …

Gophish+EwoMail 自建钓鱼服务器

GophishEwoMail 自建钓鱼服务器 文章目录 GophishEwoMail 自建钓鱼服务器1.前提准备2.搭建EwoMail邮件服务器1&#xff09;Centos7 防火墙操作2&#xff09;设置主机名3&#xff09;host配置4&#xff09;安装EwoMail5&#xff09;获取DKIM6&#xff09;端口服务介绍7&#xff…

1.2 debug的六种指令的使用,四个通用寄存器

汇编语言 首先进入环境 mount c d:masm //把c挂载在d盘中的masm当中 c: //进入c&#xff0c;进入到编译环境 dir //查看文件&#xff0c;可有可无Debug是DOS、Windows都提供的实模式&#xff08;8086 方式&#xff09;程序的调试工具。使用它可以查看CPU各种寄存器中的内容…

如何提取测试点

如何提取测试点 首先会想到从需求文档中提取测试点&#xff0c;每一次迭代之后&#xff0c;都会有需求&#xff0c;需求经理评审之后&#xff0c;我们要基于需求去写测试计划&#xff0c;包括梳理出来的测试点&#xff0c;梳理完测试点之后&#xff0c;编写对应的测试用例&…

Linux添加用户分组练习

一、复制/etc/skel目录为/home/tuser1&#xff08;/home/tuser1及其内部文件的属组和其它用户均没有任何访问权限&#xff09;。 cp -a /etc/skel /home/tuser1 chown -R tuser1:tuser1 /home/tuser1 chmod -R 700 /home/tuser1 二、编辑/etc/group文件&#xff0c;添加组h…