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


    导出数据库表文档到word。

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

    前言: 

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

    问题:

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

    实现样式如下:

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

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

     上python代码:

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

    1. # -*- coding:utf-8 -*-
    2. # 数据库验收文档导出er关系表信息
    3. import sys
    4. import os
    5. from docx.opc.oxml import parse_xml
    6. from docx.oxml.ns import nsdecls
    7. from docx.shared import RGBColor, Cm, Pt
    8. curPath = os.path.abspath(os.path.dirname(__file__))
    9. rootPath = os.path.split(curPath)[0]
    10. sys.path.append(rootPath)
    11. import pymysql
    12. from pymysql.cursors import DictCursor
    13. from docx import Document
    14. # mysql超时时间设置
    15. connect_timeout = 10
    16. # 创建mysql链接
    17. def connMysql():
    18. return pymysql.connect(host="url地址", port=数据库端口, user="数据库用户名",password="数据库密码", db="库名称", charset="utf8")
    19. # 获取数据库所有表名称
    20. def getAllDBName():
    21. conn = connMysql()
    22. # 建立游标,制定游标类型,返回字典
    23. cur = conn.cursor(DictCursor);
    24. # 执行sql语句
    25. cur.execute("select table_name,table_comment from information_schema.tables where table_schema='数据库名称'") # param
    26. # 返回查询所有
    27. res = cur.fetchall()
    28. # 关闭游标
    29. cur.close()
    30. # 关闭连接
    31. conn.close()
    32. # print("当前库下所有表的名称")
    33. # for i in res:
    34. # print(i["table_name"])
    35. return res
    36. # 获取当前表描述
    37. def getAllDBDDL(dbName, dbComment):
    38. conn = connMysql()
    39. # 建立游标,制定游标类型,返回字典
    40. cur = conn.cursor(DictCursor);
    41. # 执行sql语句
    42. cur.execute(
    43. "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'" % (
    44. dbName)) # param
    45. # 返回查询所有
    46. res = cur.fetchall()
    47. # 关闭游标
    48. cur.close()
    49. # 关闭连接
    50. conn.close()
    51. print(dbName + "[%s]" % (dbComment))
    52. for i in res:
    53. print(i)
    54. return res
    55. shading_list = locals()
    56. def leftComment(doc):
    57. # 获取第一行第二列单元格
    58. cell = doc.cell(0, 0)
    59. # 设置单元格文本
    60. cell.text = "表名"
    61. cell = doc.cell(1, 0)
    62. # 设置单元格文本
    63. cell.text = "库名"
    64. cell = doc.cell(2, 0)
    65. # 设置表格背景色
    66. for rgbsIndex in range(0, 3):
    67. shading_list['shading_elm_' + str(i)] = parse_xml(
    68. r''.format(nsdecls('w'), bgColor="#C0C0C0"))
    69. doc.rows[rgbsIndex].cells[0]._tc.get_or_add_tcPr().append(shading_list['shading_elm_' + str(i)])
    70. # 设置单元格文本
    71. cell.text = "内容描述"
    72. def rightComment(doc, dbname):
    73. cell = doc.cell(0, 1)
    74. # 设置单元格文本
    75. cell.text = dbname
    76. cell = doc.cell(1, 1)
    77. # 设置单元格文本
    78. cell.text = "zhongtie"
    79. cell = doc.cell(2, 1)
    80. # 设置单元格文本
    81. cell.text = "用于存储组数据。"
    82. def topComment(doc):
    83. cell = doc.cell(0, 0)
    84. # 设置单元格文本
    85. cell.text = "序号"
    86. cell = doc.cell(0, 1)
    87. # 设置单元格文本
    88. cell.text = "列名"
    89. cell = doc.cell(0, 2)
    90. # 设置单元格文本
    91. cell.text = "类型"
    92. cell = doc.cell(0, 3)
    93. # 设置单元格文本
    94. cell.text = "长度"
    95. cell = doc.cell(0, 4)
    96. # 设置单元格文本
    97. cell.text = "为空"
    98. cell = doc.cell(0, 5)
    99. # 设置单元格文本
    100. cell.text = "说明"
    101. cell = doc.cell(0, 6)
    102. # 设置单元格文本
    103. cell.text = "主键"
    104. # 设置表格背景色
    105. for rgbsIndex in range(0, 7):
    106. shading_list['shading_elm_' + str(i)] = parse_xml(
    107. r''.format(nsdecls('w'), bgColor="#C0C0C0"))
    108. doc.rows[0].cells[rgbsIndex]._tc.get_or_add_tcPr().append(shading_list['shading_elm_' + str(i)])
    109. # 添加一级标题
    110. # document.add_heading('我是一级标题')
    111. #
    112. # decument.add_heading('我是二级标题', level=2)
    113. #
    114. # decument.add_heading('我是段落标题', level=0)
    115. if __name__ == "__main__":
    116. # 如果需要在完成的数据内插入多个标题则这里就往后移动 例如插入三个下面就从4下标开始,方便后期完成目录的生成
    117. levelLine = 2
    118. # 获取所有的数据库表名
    119. res = getAllDBName()
    120. # word文档
    121. document = Document()
    122. # 这里遍历获取到的所有的表名 和 注释 信息
    123. for i in res:
    124. # 组装名称 例 : tableName[注释]
    125. tableAndComment = "{0}[{1}]".format(i['table_name'], i['table_comment'])
    126. # 组装名称 例 : 1.tableName[注释] 方便插入标题使用
    127. str1 = "{0}.{1}".format(levelLine, tableAndComment)
    128. # 这里写入一级标题
    129. T1_1 = document.add_heading('', level=1)
    130. # 获取run 来操作其他参数
    131. run_T1_1 = T1_1.add_run(str1)
    132. # 设置字体格式 一级标题不适合设置字体样式 会导致难看? ps:中文字体设置样式需要修改其他参数
    133. # run_T1_1.font.name = '宋体'
    134. # 设置标题颜色
    135. # 通过run修改 字体颜色
    136. run_T1_1.font.color.rgb = RGBColor(0, 0, 0)
    137. run_T1_1.font.bold = True
    138. # 获取表的DDL描述信息
    139. dbAll = getAllDBDDL(i['table_name'], i['table_comment'])
    140. # 创建表描述表格 3行 2列 实线
    141. table = document.add_table(rows=3, cols=2, style="Table Grid")
    142. # table.style.bg.color.rgb = RGBColor(255, 0, 0)
    143. # 开启高度不匹配
    144. table.rows[0].hight_mismatch = True
    145. # 开启宽度不匹配
    146. table.cell(0, 0).width_mismatch = True
    147. # 设置列 高 宽 注释:有时有用有时候又没用 不需要自行注释
    148. for topIndex in range(0, 3):
    149. # table.rows[topIndex].hight = Cm(100000.23)
    150. table.cell(topIndex, 0).width = Cm(7.53)
    151. table.cell(topIndex, 1).hight = Cm(1.23)
    152. # 填充表描述 左侧数据
    153. leftComment(table)
    154. # 填充表描述 右侧数据
    155. rightComment(table, tableAndComment)
    156. # 设置字体 大小
    157. table.style.font.size = Pt(11)
    158. # 中间插入空字符串防止两个表组合在一起
    159. document.add_paragraph("")
    160. # 创建表 根据获取的数据长度+1行 7列 实线
    161. table1 = document.add_table(rows=len(dbAll) + 1, cols=7, style="Table Grid")
    162. # 开启高度不匹配
    163. table1.rows[0].hight_mismatch = True
    164. # 开启宽度不匹配
    165. table1.cell(0, 0).width_mismatch = True
    166. # 设置列 高 宽 注释:有时有用有时候又没用
    167. for indexs in range(0, len(dbAll) + 1):
    168. # table1.rows[indexs].hight = Cm(10.88)
    169. for x in range(0, 7):
    170. table1.cell(indexs, x).width = Cm(2.11)
    171. table1.cell(indexs, x).hight = Cm(1.33)
    172. # 表头填充
    173. topComment(table1)
    174. # 游标来记录操作行
    175. dbLine = 1
    176. for db1 in dbAll:
    177. cell = table1.cell(dbLine, 0)
    178. # 设置单元格文本
    179. cell.text = str(dbLine)
    180. cell = table1.cell(dbLine, 1)
    181. # 设置单元格文本
    182. cell.text = db1["列名"]
    183. cell = table1.cell(dbLine, 2)
    184. # 设置单元格文本
    185. text1 = db1["数据类型"]
    186. cell.text = db1["数据类型"]
    187. splitStr = text1.split('(')
    188. # 拆分数据长度注释
    189. lenStr = ""
    190. if len(splitStr) > 1:
    191. lenStr = splitStr[1].split(")")
    192. cell = table1.cell(dbLine, 3)
    193. # 设置单元格文本
    194. cell.text = lenStr
    195. cell = table1.cell(dbLine, 4)
    196. # 设置单元格文本
    197. cell.text = db1["是否为空"]
    198. cell = table1.cell(dbLine, 5)
    199. # 设置单元格文本
    200. cell.text = db1["备注"]
    201. cell = table1.cell(dbLine, 6)
    202. # 设置单元格文本
    203. # 是否是主键判断 这里只适合每个表的第一列都是主键的操作,可以自行修改
    204. isKey = "Y" if dbLine == 1 else "N"
    205. cell.text = isKey
    206. table1.style.font.name = '宋体'
    207. table1.style.font.size = Pt(11)
    208. dbLine += 1
    209. levelLine += 1
    210. # 目录地址根据需要自行修改,这里是导入到脚本统计目录下
    211. document.save(r"filename.docx")

  • 相关阅读:
    Unity DropDown 组件 详解
    Py之removebg:removebg的简介、安装、使用方法之详细攻略
    IPV6地址详解
    计算机的错误计算(一百四十)
    入门力扣自学笔记121 C++ (题目编号1282)
    SpringBoot2.0数据访问之整合数据源(Druid)
    Elucidating the Design Space of Diffusion-Based Generative Models 阅读笔记
    微信小程序 springboot旅游景点门票预订服务系统
    Java学习----数据库
    河南双创蓝皮书发布:科技创新持续发力,​中创助推中部地区发展!
  • 原文地址:https://blog.csdn.net/CSDN_MrWang/article/details/127747297