【小工具】Maven项目集成poi生成数据库设计详细说明书

news2024/9/20 23:34:14

背景

编写数据库详细设计文档时经常因为数据库表过多和字段过多导致耗费大量的时间。本脚本可以自定义sql语句,查出数据库中所有表的表结构,并取需要的字段生成文档。
gitee地址:https://gitee.com/pengmqqq/mysql-to-word

1、前置准备

导入依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- excel工具 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.51</version>
        </dependency>

操作步骤

以下为main函数相关代码,相关自定义方法详见文章末尾

获取数据库连接
        String driverUrl = "jdbc:mysql://127.0.0.1:3306/test?useSSL=false&serverTimezone=UTC";
        String username = "root";
        String password = "root";
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection connection = DriverManager.getConnection(driverUrl, username, password);
获取数据库的需要生成文档的表
        //需要排除的表
        String notGenTables = "'not_gen_table1','not_gen_table1'";
        //按前缀匹配需要排除的表
        String tableNotLike = "'not_gen_%'";
        //获取数据库的表情单
        List<JSONObject> list = getTables(connection,"test",notGenTables,tableNotLike); 
创建文档
//Blank Document
        XWPFDocument document = new XWPFDocument();
        //添加标题
        XWPFParagraph titleParagraph = document.createParagraph();
        //设置段落居中
        titleParagraph.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun titleParagraphRun = titleParagraph.createRun();
        titleParagraphRun.setText(TITLE);
        titleParagraphRun.setColor("000000");
        titleParagraphRun.setFontSize(20);
生成数据库表清单
        writeSummaryTable(document, list);
生成各个表详细结构
		int i = 1;
        for (JSONObject json : list) {
            List<String[]> tableDetail = getTableDetail(connection,"cyberops", json.getString("name"));
            String remark = json.getString("remark");
            String title = (i++) + ". " + json.getString("name");
            if (remark != null && !remark.isEmpty()) {
                title += "(" + remark + ")";
            }
            writeTable(document, title, tableDetail);
        }
将文件写入磁盘
		//将文件写入磁盘
        String file = BASE_PATH + FILENAME + System.currentTimeMillis() + SUFFIX_DOC;
        FileOutputStream out = new FileOutputStream(new File(file));
        document.write(out);
        out.close();
        System.out.println("文档生成功,文档路径:"+ file);
        connection.close();

工具类(完整代码)

package com.pengmq.mysqltoword.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import java.io.File;
import java.io.FileOutputStream;
import java.math.BigInteger;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;


public class GeneratorDataToWordUtil {
    /**
     * 文档标题
     */
    public static final String TITLE = "数据库设计详细说明书";
    /**
     * 输出文档地址
     */
    public static final String BASE_PATH = "D:\\";
    /**
     * 输出文档名称
     */
    public static final String FILENAME = "数据库设计详细说明书";

    public static final String SUFFIX_DOC = ".doc";

    public static void main(String[] args) throws Exception {
        String driverUrl = "jdbc:mysql://127.0.0.1:3306/test?useSSL=false&serverTimezone=UTC";
        String username = "root";
        String password = "root";
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection connection = DriverManager.getConnection(driverUrl, username, password);
        //需要排除的表
        String notGenTables = "'not_gen_table1','not_gen_table1'";
        //按前缀匹配需要排除的表
        String tableNotLike = "'not_gen_%'";
        //获取数据库的表情单
        List<JSONObject> list = getTables(connection,"test",notGenTables,tableNotLike);

        //Blank Document
        XWPFDocument document = new XWPFDocument();
        //添加标题
        XWPFParagraph titleParagraph = document.createParagraph();
        //设置段落居中
        titleParagraph.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun titleParagraphRun = titleParagraph.createRun();
        titleParagraphRun.setText(TITLE);
        titleParagraphRun.setColor("000000");
        titleParagraphRun.setFontSize(20);

        writeSummaryTable(document, list);
        int i = 1;
        for (JSONObject json : list) {
            List<String[]> tableDetail = getTableDetail(connection,"cyberops", json.getString("name"));
            String remark = json.getString("remark");
            String title = (i++) + ". " + json.getString("name");
            if (remark != null && !remark.isEmpty()) {
                title += "(" + remark + ")";
            }
            writeTable(document, title, tableDetail);
        }

        //将文件写入磁盘
        String file = BASE_PATH + FILENAME + System.currentTimeMillis() + SUFFIX_DOC;
        FileOutputStream out = new FileOutputStream(new File(file));
        document.write(out);
        out.close();
        System.out.println("文档生成功,文档路径:"+ file);
        connection.close();
    }

    private static List<JSONObject> getTables(Connection connection,String dataBaseName,String notGenTables,String tableNotLike) throws SQLException{
        List<JSONObject> list = new ArrayList<>();
        StringBuilder sql = new StringBuilder();
        sql.append("select TABLE_NAME,TABLE_COMMENT from information_schema.tables where table_schema= ? ");
        if (null != tableNotLike) {
            sql.append(" AND table_name NOT LIKE ").append(tableNotLike);
        }
        if (null != notGenTables) {
            sql.append(" AND table_name NOT IN (").append(notGenTables).append(")");
        }
        //获取预处理statement
        PreparedStatement preparedStatement = connection.prepareStatement(sql.toString());
        //设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
        preparedStatement.setString(1, dataBaseName);
        //向数据库发出sql执行查询,查询出结果集
        ResultSet resultSet = preparedStatement.executeQuery();
        //遍历查询结果集
        while (resultSet.next()) {
            JSONObject j = new JSONObject();
            j.put("name", resultSet.getString("TABLE_NAME"));
            j.put("remark", resultSet.getString("TABLE_COMMENT"));
            list.add(j);
        }

        resultSet.close();
        preparedStatement.close();

        return list;
    }

    private static List<String[]> getTableDetail(Connection connection,String dataBaseName, String tableName) throws SQLException, ClassNotFoundException {
        List<String[]> list = new ArrayList<>();

        //定义sql语句 ?表示占位符
        String sql = "SELECT COLUMN_NAME  , COLUMN_TYPE  ,  COLUMN_DEFAULT  , if(is_nullable='YES','是','否') IS_NULLABLE  ,if(column_key='PRI','是','否' ) COLUMN_KEY,  COLUMN_COMMENT, EXTRA  FROM INFORMATION_SCHEMA.COLUMNS    WHERE  table_schema = ? and table_name = ?  ";
        //获取预处理statement
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        //设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
        preparedStatement.setString(1, dataBaseName);
        preparedStatement.setString(2, tableName);
        //向数据库发出sql执行查询,查询出结果集
        ResultSet resultSet = preparedStatement.executeQuery();
        //遍历查询结果集
        while (resultSet.next()) {
            String[] str = new String[4];
            str[0] = resultSet.getString("COLUMN_NAME");
            str[1] = resultSet.getString("COLUMN_TYPE");
            str[2] = resultSet.getString("COLUMN_COMMENT");
            str[3] = resultSet.getString("EXTRA");
            list.add(str);
        }
        resultSet.close();
        preparedStatement.close();
        return list;
    }

    private static void writeSummaryTable(XWPFDocument document, List<JSONObject> tableList) {
        //表格标题
        document.createParagraph().createRun().setText("数据表清单");
        //创建表格
        XWPFTable comTable = document.createTable();
        comTable.setCellMargins(50,50,50,50);
        //列宽自动分割
        CTTblWidth comTableWidth = comTable.getCTTbl().addNewTblPr().addNewTblW();
        comTableWidth.setType(STTblWidth.DXA);
        comTableWidth.setW(BigInteger.valueOf(9072));
        //表格第一行
        XWPFTableRow comTableRowOne = comTable.getRow(0);
        setCellValue(comTableRowOne.getCell(0), "序号", "DCDCDC", true,true);
        setCellValue(comTableRowOne.addNewTableCell(), "表名", "DCDCDC", true,true);
        setCellValue(comTableRowOne.addNewTableCell(), "功能描述", "DCDCDC", true,true);
        for (int i = 0; i < tableList.size(); i++) {
            JSONObject object = tableList.get(i);
            //新增一行
            XWPFTableRow newComTableRow = comTable.createRow();
            setCellValue(newComTableRow.getCell(0), (i + 1) + "", null, true,true);
            setCellValue(newComTableRow.getCell(1), object.getString("name"), null, true,false);
            setCellValue(newComTableRow.getCell(2), object.getString("remark"), null, true,false);
        }
    }

    private static void writeTable(XWPFDocument document, String title, List<String[]> rows) {
        //两个表格之间加个换行
        document.createParagraph().createRun().setText("\r");
        // 标题1,1级大纲
        document.createParagraph().createRun().setText(title);
        //工作经历表格
        XWPFTable comTable = document.createTable(1, 4);
        comTable.setCellMargins(50,50,50,50);

//        //列宽自动分割
        CTTblWidth comTableWidth = comTable.getCTTbl().addNewTblPr().addNewTblW();
        comTableWidth.setType(STTblWidth.DXA);
        comTableWidth.setW(BigInteger.valueOf(9072));
        //表格第一行
        XWPFTableRow comTableRowOne = comTable.getRow(0);
        setCellValue(comTableRowOne.getCell(0), "字段名", "DCDCDC",true,true);
        setCellValue(comTableRowOne.getCell(1), "字段类型", "DCDCDC",true,true);
        setCellValue(comTableRowOne.getCell(2), "数据描述", "DCDCDC",true,true);
        setCellValue(comTableRowOne.getCell(3), "备注", "DCDCDC",true,true);

        for (String[] str : rows) {
            //表格新增一行
            XWPFTableRow newComTableRow = comTable.createRow();
            for (int col = 0; col < str.length; col++) {
                XWPFTableCell cell = newComTableRow.getCell(col);
                boolean isVerCenter = true;
                boolean isHorCenter = false;
                if (col == 1){
                    isHorCenter = true;
                }
                setCellValue(cell, str[col], null, isVerCenter,isHorCenter);
            }
        }
    }

    private static void setCellValue(XWPFTableCell cell, String text, String color, boolean isVerCenter,boolean isHorCenter) {
        cell.setText(text);
        //垂直居中
        if (isVerCenter) {
            cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        }
        if (isHorCenter){
            XWPFParagraph paragraph = cell.getParagraphArray(0);
            paragraph.setAlignment(ParagraphAlignment.CENTER);
        }
        if (color == null || color.isEmpty()) {
            CTTc cttc = cell.getCTTc();
            CTTcPr tcPr = cttc.addNewTcPr();
            tcPr.addNewShd().setFill(color);

        }
    }
}

生成效果

在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uniapp微信小程序3D XR-FRAME

1.在pages.json中配置展示页面&#xff08;style中添加下面&#xff1a;&#xff09; "usingComponents": { "xr-start": "../../wxcomponents/xr-start" } 2.manifest.json中配置mp-weixin "setting" : { "urlCheck" : fal…

国人发文霸榜!命中率高达70%,这本2区SCI到底是“国人友好”还是“疯狂灌水”?

【SciencePub学术】本期&#xff0c;给大家介绍的是1本计算机类的SCI——《International Journal of Machine Learning and Cybernetics》。 优点VS缺点 • 期刊发文量逐年增多&#xff0c;命中率较高 • 国人主编坐镇&#xff0c;国人发文友好 • 混合OA&#xff0c;可选无版…

中国书法艺术

孙溟㠭浅析《大观帖》 《大观帖》是一套共十卷合集摹刻的法帖&#xff0c;大观三年《1109年》正月&#xff0c;宋徽宗所藏《淳化阁帖》刻板已经开裂损坏&#xff0c;不可修复&#xff0c;便拿出内府所藏原墨迹&#xff0c;命蔡京、龙大渊组织刻帖工作。由蔡京书写帖内的款…

【Redis】事务主从复制哨兵集群缓存分布式锁

【Redis】事务&哨兵&集群 一、事务命令合集&#xff1a; 二、主从复制断开复制性质&#xff1a;拓扑结构&#xff1a;全量复制和部分复制&#xff1a;1. replicationid/replid (复制id)&#xff08;与runid做区分&#xff09;2. offset (偏移量) psync 运⾏流程全量复制…

骨质疏松患者常用评估量表汇总,附操作步骤与评定标准

临床常用量表来评估患者的骨健康状况&#xff0c;常笑医学整理了4个临床常用的骨质疏松患者评估量表&#xff0c;支持下载和在线使用&#xff0c;供临床医护人员参考。 01 国际骨质疏松基金会(IOF)骨质疏松症风险一分钟测试题 &#xff08;完整量表请点击量表名称查看&#xff…

Transformer模型《Attention Is All You Need》

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl1. 模型起源与发展 1.1 2017年论文《Attention Is All You Need》 2017年,谷歌大脑团队在论文《Attention Is All You Need》中首次提出了Transformer模型,该模型摒弃了传统的循环神经网络(RN…

关于主流电商平台|淘宝|拼多多|抖音|1688官方平台接口的接入和返回

taobao.trades.sold.get( 查询卖家已卖出的交 搜索当前会话用户作为卖家已卖出的交易数据&#xff08;只能获取到三个月以内的交易信息&#xff09; 1. 返回的数据结果是以订单的创建时间倒序排列的。 2. 返回的数据结果只包含了订单的部分数据&#xff0c;可通过taobao.trade…

我愿称之为: jjVioMap (小提琴热图)

吾将上下而求索 1Introduction Here supply a geom_jjviomap function to visualize gene expression or other data in a heatmap-like way. The geom_jjviomap can still retain data distribution informations through violin graphs. 链接: https://github.com/junjunlab/…

论文解读汇总(目标检测、目标跟踪、语义分割....)定期更新

微信公众号 猫脸码客 论文解读文章 第1期 论文解读——YOLOv1&#xff08;目标检测&#xff09; 第2期 论文解读——YOLOv2&#xff08;目标检测&#xff09; 第3期 论文解读——YOLOv3&#xff08;目标检测&#xff09; 第4期 论文解读——YOLOv4&#xff08;目标检测&…

惊喜!万博智云亮相2024数博会和第三届828 B2B企业节

摘要 万博智云作为2024 828 B2B企业节铂金合作伙伴&#xff0c;在2024中国国际大数据产业博览会的828 B2B企业节开幕式上亮相&#xff0c;并参加了本次828企业节的一系列活动&#xff0c;包括在华为展台现场开展的“‘云上大咖团’直面数博会现场”的直播上发表了主题分享。 8…

最新发布!Windows 11 23H2 64位专业精简版

今天系统之家小编给大家带来2024年8月28日更新的Windows11 23H2精简版系统&#xff0c;该版本系统经过适度的精简优化&#xff0c;大部分功能都保留下来&#xff0c;可以轻松满足大家的日常使用需求。系统的兼容性强大&#xff0c;能完美兼容新老机型&#xff0c;安装后时刻运作…

图像压缩编码(2)有损压缩--变换编码

#灵感# 接上文&#xff0c;继续讲解第二种有损压缩&#xff0c;但是内容太多了&#xff0c;浅尝就行。 有损压缩编码以丢失一部分信息为代价&#xff0c;换来较高的压缩比。有损压缩主要分为几类&#xff1a;预测编码、变换编码、子带编码、模型编码。 变换编码 变换编码与预…

Java、python、php版 舞蹈工作室管理系统 舞蹈课程预约平台(源码、调试、LW、开题、PPT)

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人 八年开发经验&#xff0c;擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等&#xff0c;大家有这一块的问题可以一起交流&…

Redis网络通信模型

1.1. Java IO读写原理 不管是Socket的读写仍是文件的读写&#xff0c;在Java层面的应用开发或者是linux系统底层开发&#xff0c;都属于输入input和输出output的处理&#xff0c;简称为IO读写。在原理上和处理流程上&#xff0c;都是一致的。区别在于参数的不一样。用户程序进…

Kaggle竞赛——手写数字识别(Digit Recognizer)

目录 1. 数据集介绍2. 数据分析3. 数据处理与封装3.1 数据集划分3.2 将数据转为tensor张量3.3 数据封装 4. 模型训练4.1 定义功能函数4.1 resnet18模型4.3 CNN模型4.4 FCNN模型 5. 结果分析5.1 混淆矩阵5.2 查看错误分类的样本 6. 加载最佳模型7. 参考文献 本次手写数字识别使用…

【书生2.5】XTuner 微调个人小助手认知

XTuner 微调个人小助手认知 【Intern Studio的gpu不足。本实验使用自有服务器】 1 环境安装 # 创建虚拟环境 conda create -n xtuner python3.10 -y# 激活虚拟环境&#xff08;注意&#xff1a;后续的所有操作都需要在这个虚拟环境中进行&#xff09; conda activate xtuner…

同样128个内核,AMD霄龙9755性能翻倍:Zen 5架构下的性能飞跃

近日&#xff0c;AMD在服务器处理器领域再次展示了其强大的技术实力&#xff0c;随着AMD EPYC“Turin”处理器发布日期的临近&#xff0c;其基准测试结果也开始浮出水面。硬件爱好者博主9550pro近期分享了AMD 128核EPYC 9755“Turin”处理器在7zip压缩/解压缩基准测试中的跑分数…

深圳MES系统在电子制造业中的应用体现

深圳是中国电子制造业的重要基地&#xff0c;许多电子制造企业在深圳地区都在应用MES系统来优化生产管理、提高生产效率和产品质量。深圳MES系统在电子制造业中的应用主要体现在以下几个方面&#xff1a; 生产计划管理&#xff1a;电子制造企业通常面临订单量大、产品种类多的情…

【知识图谱】4、LLM大模型结合neo4j图数据库实现AI问答的功能

昨天写了一篇文章&#xff0c;使用fastapi直接操作neo4j图数据库插入数据的例子&#xff0c; 本文实现LLM大模型结合neo4j图数据库实现AI问答功能。 废话不多说&#xff0c;先上代码 import gradio as gr from fastapi import FastAPI, HTTPException, Request from pydantic…

分享使用智狐联创AI助手生成的一个食品选择器网页

先看效果&#xff1a; 使用的是智狐超强模型&#xff0c;只有一个html网页&#xff0c;点击开始会有动画的选择动画。效果很不错&#xff0c;你可以更改成任意类似场景使用&#xff0c;如&#xff1a;抽奖等等。感兴趣的可以去搜索官网试试&#xff0c;也有免费模型。https://w…