开源项目:数据库表结构生成文档工具
目录
一、软件介绍
二、技术框架
三、功能介绍
四、代码展示
1、获取数据库信息部分代码
2、导出Html文档代码
五、运行效果
六、项目开源地址
一、软件介绍
今天给大家分享我自己编写的数据库表结构文档生成工具,方便大家在实际开发当中,可以很方便导出业务系统的表结构,也可以作为项目验收文档中数据库设计文档使用。这样可以大大减少编写数据库表结构文档的时间,有需要的朋友欢迎下载或者沟通交流!
二、技术框架
- 编程语言:C# ( Net Framework4.5.5)
- 数据库技术框架:Dapper
- 导出Word文档:NPOI
- 访问方式:WinForm窗体应用程序,Windows操作系统可以直接运行
三、功能介绍
- 支持SQLServer、MySQL(5.7、8.0)、SQLite 三种类型的数据,持续更新
- 支持Word、Html、MarkDown 三种格式的导出
- 导出内容包含数据表(字段详情、字段注释、长度、默认值等)、创建表脚本、视图及视图脚本、存储过程及脚本
- 支持生成文档的同时直接打开文档
- 支持数据库备份(目前只支持SQLServer导出bak备份文件)
四、代码展示
1、获取数据库信息部分代码
/// <summary>/// 获取数据库字符串/// </summary>/// <param name="servername"></param>/// <param name="uid"></param>/// <param name="pwd"></param>/// <param name="db"></param>/// <returns></returns>public string GetConnectioning(string servername, string uid, string pwd, string db, string port){return string.Format("server={0};uid={1};pwd={2};database={3}", servername, uid, pwd, db);}/// <summary>/// 获取数据库列表/// </summary>/// <param name="conStr"></param>/// <returns></returns>public List<string> GetDBNameList(string conStr){//List<DBName> list =new List<DBName>();string sql = "select [name] from master.dbo.sysdatabases where DBId>6 Order By [Name] ";try{using (SqlConnection connection = new SqlConnection(conStr)){var list = connection.Query<string>(sql).ToList();return list;}}catch{return null;}}public List<DBModel> GetDBList(string conStr){//List<DBName> list =new List<DBName>();string sql = "select [name] from master.dbo.sysdatabases where DBId>6 Order By [Name] ";try{using (SqlConnection connection = new SqlConnection(conStr)){var list = connection.Query<DBModel>(sql).ToList();return list;}}catch{return null;}}/// <summary>/// 获取特定数据库的表名列表/// </summary>/// <param name="conStr"></param>/// <returns></returns>public List<TableModel> GetDBTableList(string conStr, string dbName = ""){var list = new List<TableModel>();//string sql = "SELECT TABLE_NAME as name FROM INFORMATION_SCHEMA.TABLES where TABLE_TYPE='BASE TABLE' ";string sql = "select a.name AS tableName,CONVERT(NVARCHAR(100),isnull(g.[value],'')) AS tableDesc from sys.tables a left join sys.extended_properties g on (a.object_id = g.major_id AND g.minor_id = 0)";try{using (SqlConnection connection = new SqlConnection(conStr)){list = connection.Query<TableModel>(sql).ToList();}}catch{}return list;}/// <summary>/// 获取特定数据库里面的存储过程/// </summary>/// <param name="conStr"></param>/// <param name="db"></param>/// <returns></returns>public List<ProcModel> GetProcList(string conStr, string dbName = ""){var list = new List<ProcModel>();string sql = @" select name as procName, (select text from syscomments where id=OBJECT_ID(name)) as proDerailsfrom dbo.sysobjects o where OBJECTPROPERTY(id, N'IsProcedure') = 1 order by name ";try{ using (SqlConnection connection = new SqlConnection(conStr)){list = connection.Query<ProcModel>(sql).ToList();}}catch{}return list;}/// <summary>/// 获取特定数据库里面的视图/// </summary>/// <param name="conStr"></param>/// <param name="db"></param>/// <returns></returns>public List<ViewModel> GetViewList(string conStr, string dbName = ""){var list = new List<ViewModel>();string sql = @" select name as viewName, (select text from syscomments where id=OBJECT_ID(name)) as viewDerailsfrom dbo.sysobjects o where OBJECTPROPERTY(id, N'IsView') = 1 order by name ";try{ using (SqlConnection connection = new SqlConnection(conStr)){list = connection.Query<ViewModel>(sql).ToList();}}catch{}return list;}/// <summary>/// 获取字段的信息/// </summary>/// <param name="tableName"></param>/// <param name="conStr"></param>/// <returns></returns>public List<TableDetail> GetTableDetail(string tableName, string conStr, string dbName = ""){var list = new List<TableDetail>();StringBuilder sb = new StringBuilder();sb.Append("SELECT [index] = a.colorder, Title = a.name, isMark = CASE WHEN COLUMNPROPERTY(a.id, a.name, 'IsIdentity') = 1 THEN '1' ELSE '0' END, ");sb.Append("isPK = CASE WHEN EXISTS(SELECT 1 FROM sysobjects WHERE xtype = 'PK' AND parent_obj = a.id AND name IN(SELECT name FROM sysindexes WHERE indid IN(SELECT indid FROM sysindexkeys WHERE id = a.id AND colid = a.colid)) ) THEN '1' ELSE '0' END, ");sb.Append(" FieldType = b.name,fieldLenth = COLUMNPROPERTY(a.id, a.name, 'PRECISION'),isAllowEmpty = CASE WHEN a.isnullable = 1 THEN '1' ELSE '0' END, defaultValue = ISNULL(e.text, ''), fieldDesc = ISNULL(g.[value], '') ");sb.Append("FROM syscolumns a LEFT JOIN systypes b ON a.xusertype = b.xusertype INNER JOIN sysobjects d ON a.id = d.id AND d.xtype = 'U' AND d.name <> 'dtproperties' LEFT JOIN syscomments e ON a.cdefault = e.id ");sb.Append("LEFT JOIN sys.extended_properties g ON a.id = G.major_id AND a.colid = g.minor_id LEFT JOIN sys.extended_properties f ON d.id = f.major_id AND f.minor_id = 0");//--如果只查询指定表,加上此红色where条件,tablename是要查询的表名;去除红色where条件查询说有的表信息sb.Append("WHERE d.name = '" + tableName + "' ORDER BY a.id, a.colorder, d.name");try{using (SqlConnection connection = new SqlConnection(conStr)){list = connection.Query<TableDetail>(sb.ToString()).ToList();}}catch{ }return list;}
2、导出Html文档代码
/// <summary>/// 生成html文件/// </summary>/// <param name="list"></param>/// <param name="conStr"></param>/// <param name="db"></param>/// <param name="type"></param>public void CreateToHtml(List<TableModel> list, string conStr, string db, int type, List<string> checkList){StringBuilder sb = new StringBuilder();sb.Append("<html><meta charset=\"utf-8\" /><meta http-equiv = \"Content-Language\" content = \"zh-CN\" >");sb.Append("<head><title>数据库说明文档</title><body>");sb.Append("<style type=\"text/css\">\n");sb.Append("body { font-size: 9pt;}\n");sb.Append(".styledb { font-size: 14px; }\n");sb.Append(".styletab {font-size: 14px;padding-top: 15px; }\n</style></head><body>");sb.Append("<h1 style=\"text-align:center;\">" + db + "数据库说明文档</h1>");GetDBService(type);#region 创建一个表格if (checkList.Where(m => m.Equals("表")).Count() > 0){sb.Append("<h2>一、表结构</h2>");sb.Append("");sb.Append("");if (list.Count > 0){foreach (var item in list){if (item.tableDesc != null && item.tableDesc != ""){sb.Append("<h3>表名:" + item.tableName + "(" + item.tableDesc + ")</h3>");}else{sb.Append("<h3>表名:" + item.tableName + "</h3>");}sb.Append(" <table cellspacing=\"0\" cellpadding=\"5\" border=\"1\" width=\"100%\" bordercolorlight=\"#4F7FC9\" bordercolordark=\"#D3D8E0\">");sb.Append("<thead bgcolor=\"#E3EFFF\"> <th>序号</th><th>字段名称</th><th>标识</th><th>主键</th><th>字段类型</th><th>字段长度</th><th>允许空值</th><th>字段默认值</th><th>字段备注</th></thead>");sb.Append("<tbody>");//从第二行开始 因为第一行是表头int i = 1;var tabledetaillist = service.GetTableDetail(item.tableName, conStr, db);if (tabledetaillist != null && tabledetaillist.Count > 0){foreach (var itm in tabledetaillist){sb.Append("<tr>");sb.Append("<td>" + itm.index + "</td>");sb.Append("<td>" + itm.Title + "</td>");sb.Append("<td>" + itm.isMark + "</td>");sb.Append("<td>" + itm.isPK + "</td>");sb.Append("<td>" + itm.FieldType + "</td>");sb.Append("<td>" + itm.fieldLenth + "</td>");sb.Append("<td>" + itm.isAllowEmpty + "</td>");sb.Append("<td>" + itm.defaultValue + "</td>");sb.Append("<td>" + itm.fieldDesc + "</td>");sb.Append("</tr>");i++;}}sb.Append("</tbody></table>");sb.Append("<h4>" + item.tableName + "建表脚本</h4><br/>");sb.Append("<span>" + service.GetTableSQL(item.tableName, conStr) + "</span>");}}}#endregion#region 存储过程if (checkList.Where(m => m.Equals("存储过程")).Count() > 0){List<ProcModel> proclist = new List<ProcModel>();proclist = service.GetProcList(conStr, db);sb.Append("<h2>二、存储过程</h2>");if (proclist != null && proclist.Count > 0){foreach (var item in proclist){sb.Append("<h3>存储过程名称:" + item.procName + "</h3>");sb.Append("<span>" + item.proDerails + "</span>");}}}#endregion#region 视图if (checkList.Where(m => m.Equals("视图")).Count() > 0){List<ViewModel> viewlist = new List<ViewModel>();viewlist = service.GetViewList(conStr, db);sb.Append("<h2>三、视图</h2>");if (viewlist.Count > 0){foreach (var item in viewlist){sb.Append("<h3>视图名称:" + item.viewName + "</h3>");sb.Append("<span>" + item.viewDerails + "</span>");}}}#endregionsb.Append("</body></html>");sb.ToString();string filename = db + "-数据库说明文档";//文件名SaveFileDialog saveDialog = new SaveFileDialog();saveDialog.DefaultExt = "html";saveDialog.Filter = "html文件|*.html";saveDialog.FileName = filename;saveDialog.ShowDialog();filename = saveDialog.FileName;if (filename.IndexOf(":") < 0) return; //被点了取消 StreamWriter sw1 = new StreamWriter(saveDialog.FileName, false);sw1.WriteLine(sb);sw1.Close();System.Diagnostics.Process.Start(filename);}
五、运行效果
应用程序主界面

支持三种生成文档类型:每次只能选择一种,推荐使用markdown格式

Word文档生成效果

Html文档生成效果

MarkDown文档效果

针对SQLServer数据库备份

六、项目开源地址
GitHub:https://github.com/hgmsq/SqlToDocTool
Gitee:https://gitee.com/hgm1989/SqlToDocTool
Gitcode:https://gitcode.net/xishining/SqlToDocTool
相关文章:
开源项目:数据库表结构生成文档工具
目录 一、软件介绍 二、技术框架 三、功能介绍 四、代码展示 1、获取数据库信息部分代码 2、导出Html文档代码 五、运行效果 六、项目开源地址 一、软件介绍 今天给大家分享我自己编写的数据库表结构文档生成工具,方便大家在实际开发当中,可以很方便导出…...
spring的两种拦截器HandlerIntercepter和MethodIntercepter
介绍 Spring有两种拦截器提供给我们使用,一种是HandlerIntercepter,另一种是MethodIntercepter。这两种的来源不同,实现方式也不同,具体的下面来看一下。 HandlerIntercepter 来源 来源于spring-webmvc包 HandlerIntercepter拦…...
初级算法-字符串
主要记录算法和数据结构学习笔记,新的一年更上一层楼! 初级算法-字符串一、反转字符串二、反转字符串(二)三、替换空格四、翻转字符串里的单词五、左旋转字符串六、实现 strStr()七、重复的子字符串字符串中元素只能是字符String…...
华为OD机试题 - 寻找目标字符串(JavaScript)| 机考必刷
更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为…...
删除Terminating状态的namespace:cattle-system
这里以cattle-system为例!执行删除命令后namespace(也是用其他k8s object)仍然存在,首先执行 kubectl edit namespace cattle-system 查看是否存在spec.finalizers: kubernetes,如: spec: finalizers:…...
MiniOB 并发B+树实现解析
MiniOB 是 OceanBase 联合华中科技大学推出的一款用于教学的小型数据库系统,希望能够帮助数据库爱好者系统性的学习数据库原理与实战。 B 树介绍 B 树是传统数据库中常见的索引数据结构,比如MySQL、PostgreSQL都实现了B树索引。B 树是一个平衡多叉树&am…...
SpringCloud负载均衡服务调用——Ribbon
Ribbon 本专栏学习内容来自尚硅谷周阳老师的视频 有兴趣的小伙伴可以点击视频地址观看 简介 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。 简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算…...
各种邮箱服务软件对比
1.宝塔邮局管理器 特点:简单易用,可视化操作,小白也能搞,还有备份功能,一般足够用了 缺点:稳定性真是差,隔三差五的不能收发.没有接口,不能任意修改邮箱密码,只能管理员修改 注意要点:一定要开启ssl,否则有些邮箱给你发邮件你收不到 建议:不要入坑.坏了之后没法修复,哭都没地方…...
相机单独标定的实现过程[autoware标定]、tmp文件的查看方式
安装了autoware1.13和calibration标定包,发现实现相机单独标定的过程较为坎坷,参考了一些博主的方法,发现下面的过程更加适合自己,做个笔记。 1安装标定箱(与calibration标定包的安装并不冲突) 标定工具箱…...
4.10.1、IP 多播技术的相关基本概念
多播(Multicast,也称为组播)是一种实现 “一对多” 通信的技术,与传统单播“一对一”通信相比,多播可以极大地节省网络资源。 在因特网上进行的多播,称为 IP 多播。 1、单播 & 多播 如下所示…...
PIGOSS BSM监控国产数据库Oscar
前言神通数据库(原OSCAR数据库)是天津神舟通用数据技术有限公司(简称“神舟通用公司”)拥有自主知识产权的企业级、大型通用关系型数据库管理系统。PIGOSS BSM作为网利友联科技完全自主研发的纯国产基础 IT 架构运行状态监测平台软件…...
Spring Boot中文件上传
Spring Boot中文件上传 前言 本篇主要参考Spring官方文档,整理了Spring Boot中文件上传如何实现,以及在代码中使用RestTemplate和HttpClient两种方式实现文件上传。 创建Spring Boot项目 首先创建一个Spring Boot Web项目,使用的Spring B…...
Github上传大文件(>25MB)教程
Github上传大文件(>25MB)教程Github上传大文件(>25MB)教程安装git安装Git Large File Storage实例踩坑点1:failed to push some refs to踩坑点2:main与master踩坑点3:Failed to connect t…...
面试官:mysql索引会缓存内存吗?
文章目录 InnoDB缓冲池如何设置方法一:使用 `innodb_buffer_pool_size` 变量方法二:修改my.ini配置文件InnoDB缓冲池 InnoDB存储引擎是基于磁盘存储表文件和索引的,并将数据按页的方式管理,由于访问磁盘的速度较慢,多次访问磁盘会造成数据库性能的下降,为此,InnoDB在内…...
bs4解析数据和csv文件
\b 检测所在的位置是否是单词边界(任何可以将不同的单词进行区分的符号:空白符号,标点符号,字符串开头,字符串结尾) ^ 检测是否是字符串开头 $ 检测是否是字符串结尾 csv保存数据 什么是csv文件 读操作…...
Linux中Buffer和Cache的区别
Linux中Buffer和Cache的区别 free命令中会有一项buff/cache, 通过man free可以看到这里的关于buff/cache的介绍 buff/cache包含两部分 buffers:内核缓存区用到的内存,对应/proc/meminfo中Buffers的值 cache:内核页缓存和Slab用到的内存,对应/proc/mem…...
Docker 镜像使用
目录 1、列出镜像列表 2、获取一个新的镜像 3、查找镜像 4、拖取镜像 5、删除镜像 6、创建镜像 a.更新镜像 b.构建镜像 设置镜像标签 当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 …...
Java阶段一Day10
Java阶段一Day10 文章目录Java阶段一Day10抽象类和抽象方法接口案例小练习引用类型数组教师总结回顾:精华笔记:笔记:补充:抽象类和抽象方法 关键字:abstract 只有方法的定义,没有具体的实现(连…...
触摸屏与PLC之间如何快速实现无线PPI通信?
PPI协议是西门子为S7-200专门开发的通信协议,是不开放的协议,CPU自带的两个通信口(Port0,Port1)均支持该协议,S7-200的一些通信模块也支持PPI协议。编程软件Micro/WIN与CPU进行编程通信也使用PPI协议&#…...
【华为OD机试 2023最新 】 羊、狼、农夫过河(C++ 100%)
题目描述 羊、狼、农夫都在岸边,当羊的数量小于狼的数量时,狼会攻击羊,农夫则会损失羊。农夫有一艘容量固定的船,能够承载固定数量的动物。 要求求出不损失羊情况下将全部羊和狼运到对岸需要的最小次数。 只计算农夫去对岸的次数,回程时农夫不会运送羊和狼。 备注:农…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
协议转换利器,profinet转ethercat网关的两大派系,各有千秋
随着工业以太网的发展,其高效、便捷、协议开放、易于冗余等诸多优点,被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口,具有实时性、开放性,使用TCP/IP和IT标准,符合基于工业以太网的…...
