python自动化导出数据库表结构到word

导出数据库表文档到word。

使用pyhton的python-docx框架实现导出数据库表结构为word格式。

前言: 

        本人自学python,语法不精通,参考人员注意甄别。

问题:

        由于近期甲方项目需要验收,需要完成数据库er,和数据库文档,由于没有搜索到需要的插件/方案(网上只有半自动化,每次只能自己手动操作一个个导出,效率太低)故自己尝试手写了一个。

实现样式如下:

下面是单个的样式,代码内部会遍历所有的表,有多少个表就会往word内写入多少个表格

后面只需要自己配置头部的公司信息,和其他自己所需要的文件即可,最后手动生成目录

 上python代码:

部分代码是写死的,例如(上图)表左,表头

# -*- coding:utf-8 -*-
# 数据库验收文档导出er关系表信息
import sys
import os
from docx.opc.oxml import parse_xml
from docx.oxml.ns import nsdecls
from docx.shared import RGBColor, Cm, Pt
curPath = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.split(curPath)[0]
sys.path.append(rootPath)
import pymysql
from pymysql.cursors import DictCursor
from docx import Document

# mysql超时时间设置
connect_timeout = 10

# 创建mysql链接
def connMysql():
    return pymysql.connect(host="url地址", port=数据库端口, user="数据库用户名",password="数据库密码", db="库名称", charset="utf8")


# 获取数据库所有表名称
def getAllDBName():
    conn = connMysql()
    # 建立游标,制定游标类型,返回字典
    cur = conn.cursor(DictCursor);
    # 执行sql语句
    cur.execute("select table_name,table_comment from information_schema.tables where table_schema='数据库名称'")  # param
    # 返回查询所有
    res = cur.fetchall()
    # 关闭游标
    cur.close()
    # 关闭连接
    conn.close()
    # print("当前库下所有表的名称")
    # for i in res:
    #     print(i["table_name"])
    return res


# 获取当前表描述
def getAllDBDDL(dbName, dbComment):
    conn = connMysql()
    # 建立游标,制定游标类型,返回字典
    cur = conn.cursor(DictCursor);
    # 执行sql语句
    cur.execute(
        "SELECT COLUMN_NAME 列名, COLUMN_TYPE 数据类型,DATA_TYPE 字段类型,IS_NULLABLE 是否为空,COLUMN_DEFAULT 默认值,COLUMN_COMMENT 备注 FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = 'zhongtie' AND table_name = '%s'" % (
            dbName))  # param
    # 返回查询所有
    res = cur.fetchall()
    # 关闭游标
    cur.close()
    # 关闭连接
    conn.close()
    print(dbName + "[%s]" % (dbComment))
    for i in res:
        print(i)
    return res



shading_list = locals()


def leftComment(doc):
    # 获取第一行第二列单元格
    cell = doc.cell(0, 0)
    # 设置单元格文本
    cell.text = "表名"
    cell = doc.cell(1, 0)
    # 设置单元格文本
    cell.text = "库名"
    cell = doc.cell(2, 0)
    # 设置表格背景色
    for rgbsIndex in range(0, 3):
        shading_list['shading_elm_' + str(i)] = parse_xml(
            r'<w:shd {} w:fill="{bgColor}"/>'.format(nsdecls('w'), bgColor="#C0C0C0"))
        doc.rows[rgbsIndex].cells[0]._tc.get_or_add_tcPr().append(shading_list['shading_elm_' + str(i)])
    # 设置单元格文本
    cell.text = "内容描述"


def rightComment(doc, dbname):
    cell = doc.cell(0, 1)
    # 设置单元格文本
    cell.text = dbname
    cell = doc.cell(1, 1)
    # 设置单元格文本
    cell.text = "zhongtie"
    cell = doc.cell(2, 1)
    # 设置单元格文本
    cell.text = "用于存储组数据。"


def topComment(doc):
    cell = doc.cell(0, 0)
    # 设置单元格文本
    cell.text = "序号"
    cell = doc.cell(0, 1)
    # 设置单元格文本
    cell.text = "列名"
    cell = doc.cell(0, 2)
    # 设置单元格文本
    cell.text = "类型"
    cell = doc.cell(0, 3)
    # 设置单元格文本
    cell.text = "长度"
    cell = doc.cell(0, 4)
    # 设置单元格文本
    cell.text = "为空"
    cell = doc.cell(0, 5)
    # 设置单元格文本
    cell.text = "说明"
    cell = doc.cell(0, 6)
    # 设置单元格文本
    cell.text = "主键"
    # 设置表格背景色
    for rgbsIndex in range(0, 7):
        shading_list['shading_elm_' + str(i)] = parse_xml(
            r'<w:shd {} w:fill="{bgColor}"/>'.format(nsdecls('w'), bgColor="#C0C0C0"))
        doc.rows[0].cells[rgbsIndex]._tc.get_or_add_tcPr().append(shading_list['shading_elm_' + str(i)])

# 添加一级标题
# document.add_heading('我是一级标题')
#
# decument.add_heading('我是二级标题', level=2)
#
# decument.add_heading('我是段落标题', level=0)

if __name__ == "__main__":
    # 如果需要在完成的数据内插入多个标题则这里就往后移动 例如插入三个下面就从4下标开始,方便后期完成目录的生成
    levelLine = 2
    # 获取所有的数据库表名
    res = getAllDBName()
    # word文档
    document = Document()
    # 这里遍历获取到的所有的表名 和 注释 信息
    for i in res:
        # 组装名称 例 : tableName[注释]
        tableAndComment = "{0}[{1}]".format(i['table_name'], i['table_comment'])
        # 组装名称 例 : 1.tableName[注释] 方便插入标题使用
        str1 = "{0}.{1}".format(levelLine, tableAndComment)
        # 这里写入一级标题
        T1_1 = document.add_heading('', level=1)
        # 获取run 来操作其他参数
        run_T1_1 = T1_1.add_run(str1)
        # 设置字体格式 一级标题不适合设置字体样式 会导致难看? ps:中文字体设置样式需要修改其他参数
        # run_T1_1.font.name = '宋体'
        # 设置标题颜色
        # 通过run修改 字体颜色
        run_T1_1.font.color.rgb = RGBColor(0, 0, 0)
        run_T1_1.font.bold = True
        # 获取表的DDL描述信息
        dbAll = getAllDBDDL(i['table_name'], i['table_comment'])
        # 创建表描述表格 3行 2列 实线
        table = document.add_table(rows=3, cols=2, style="Table Grid")
        # table.style.bg.color.rgb = RGBColor(255, 0, 0)
        # 开启高度不匹配
        table.rows[0].hight_mismatch = True
        # 开启宽度不匹配
        table.cell(0, 0).width_mismatch = True
        # 设置列 高 宽 注释:有时有用有时候又没用 不需要自行注释
        for topIndex in range(0, 3):
            # table.rows[topIndex].hight = Cm(100000.23)
            table.cell(topIndex, 0).width = Cm(7.53)
            table.cell(topIndex, 1).hight = Cm(1.23)
        # 填充表描述 左侧数据
        leftComment(table)
        # 填充表描述 右侧数据
        rightComment(table, tableAndComment)
        # 设置字体 大小
        table.style.font.size = Pt(11)
        # 中间插入空字符串防止两个表组合在一起
        document.add_paragraph("")
        # 创建表 根据获取的数据长度+1行 7列 实线
        table1 = document.add_table(rows=len(dbAll) + 1, cols=7, style="Table Grid")
        # 开启高度不匹配
        table1.rows[0].hight_mismatch = True
        # 开启宽度不匹配
        table1.cell(0, 0).width_mismatch = True
        # 设置列 高 宽 注释:有时有用有时候又没用
        for indexs in range(0, len(dbAll) + 1):
            # table1.rows[indexs].hight = Cm(10.88)
            for x in range(0, 7):
                table1.cell(indexs, x).width = Cm(2.11)
                table1.cell(indexs, x).hight = Cm(1.33)
        # 表头填充
        topComment(table1)
        # 游标来记录操作行
        dbLine = 1
        for db1 in dbAll:
            cell = table1.cell(dbLine, 0)
            # 设置单元格文本
            cell.text = str(dbLine)
            cell = table1.cell(dbLine, 1)
            # 设置单元格文本
            cell.text = db1["列名"]

            cell = table1.cell(dbLine, 2)
            # 设置单元格文本
            text1 = db1["数据类型"]
            cell.text = db1["数据类型"]
            splitStr = text1.split('(')
            # 拆分数据长度注释
            lenStr = ""
            if len(splitStr) > 1:
                lenStr = splitStr[1].split(")")
            cell = table1.cell(dbLine, 3)
            # 设置单元格文本
            cell.text = lenStr

            cell = table1.cell(dbLine, 4)
            # 设置单元格文本
            cell.text = db1["是否为空"]

            cell = table1.cell(dbLine, 5)
            # 设置单元格文本
            cell.text = db1["备注"]

            cell = table1.cell(dbLine, 6)
            # 设置单元格文本
            # 是否是主键判断 这里只适合每个表的第一列都是主键的操作,可以自行修改
            isKey = "Y" if dbLine == 1 else "N"
            cell.text = isKey
            table1.style.font.name = '宋体'
            table1.style.font.size = Pt(11)
            dbLine += 1
        levelLine += 1
    # 目录地址根据需要自行修改,这里是导入到脚本统计目录下
    document.save(r"filename.docx")

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值