python导出excel-表结构文档生成

为了体验python连接mysql数据库和导出excel,写一个导出表结构的脚本

创建、激活虚拟环境

python3 -m venv py_env
source py_env/bin/activate

安装依赖包

pip install xlwt
pip install pymysql

coding

"""
    导出表结构文档到excel
    @author Jenson
"""
import xlwt
import pymysql

"""
    可配置参数
"""
# 定义数据库连接信息
db_host = 'db_ip'
db_user = 'username'
db_passwd = 'passworld'
db_port = 3306
# 需要导出表结构的库
export_db_scheme = 'scheme'
# 导出索引
show_index_flag = True
# True:只导出 TABLE_COMMENT 不为空的表;False:导出所有表
existCommentFlag = False
# 使用表名作为sheet的名称;False以comment作为sheet名,True以tableName作为sheet名
sheetNameEqualToTableNameFlag = False
"""
    ----------------------------
"""
# 从 information_schema 中导出表信息
db_scheme = 'information_schema'

#链接数据库需要先导入库
#python3中不支持mysqldb
db=pymysql.connect(host=db_host,user=db_user,passwd=db_passwd,db=db_scheme,port=db_port)

# 使用cursor()方法获取操作游标
cur = db.cursor()

#查询操作 注意:数据列表的顺序同SELECT语句字段排序一致
select_sql = "SELECT col.TABLE_NAME, tab.TABLE_COMMENT, col.COLUMN_NAME, col.COLUMN_TYPE, col.IS_NULLABLE, col.COLUMN_DEFAULT, col.COLUMN_COMMENT, col.COLUMN_KEY, col.EXTRA"
from_sql = " FROM COLUMNS col,TABLES tab"
where_sql = " WHERE col.TABLE_SCHEMA= '"+export_db_scheme+"' AND tab.TABLE_NAME = col.TABLE_NAME AND tab.TABLE_SCHEMA = col.TABLE_SCHEMA"
order_sql = " ORDER BY TABLE_NAME"
sql =  select_sql + from_sql + where_sql + order_sql

tableStructureData = [];

try:
    cur.execute(sql)
    results = cur.fetchall()
    # 遍历结果,处理数据
    table_name = "";
    for row in results :
        if existCommentFlag and row[1] == '' :
            continue
        if row[0] != table_name and row[0] != '' :
            table_name = row[0]
            table = {}
            tableStructureData.append(table)
            table["table_name"] = table_name
            if sheetNameEqualToTableNameFlag:
                table["table_comment"] = row[0]
            else:
                if row[1] == "" :
                    table["table_comment"] = row[0]
                else:
                    table["table_comment"] = row[1]
            # 对字符串长度进行处理,确保不要超出excelsheet页长度
            if len(table["table_comment"])>30:
                table["table_comment"]=table["table_comment"][0:30]
            table["column"] = []
        else:
            pass
        colMap = {}
        colMap["name"] = row[2]
        if row[3].count("(") :
            colMap["type"] = row[3][0:row[3].find("(")]
            colMap["length"] = row[3][row[3].find("(")+1:-1]
        else:
            colMap["type"] = row[3]
            colMap["length"] = ""
        if row[4]=="YES" :
            colMap["nullable"] = "是"
        else:
            colMap["nullable"] = "否"
        colMap["default"] = row[5]
        if row[6] == '' and row[7] == 'PRI':
            if row[8] == 'auto_increment':
                colMap["description"] = '表ID,主键,自增,供其他表做外键'
            else:
                colMap["description"] = '表ID,主键,供其他表做外键'
        else:
            colMap["description"] = row[6]

        table["column"].append(colMap)
    # 如果需要导出索引,再次遍历组合好的数据,插入索引
    if show_index_flag :
        for table in tableStructureData:
            #查询索引
            cur.execute("SHOW index FROM "+export_db_scheme+"."+table["table_name"])
            indexResults = cur.fetchall()
            indexMap = {}
            for indexRow in indexResults:
                if indexRow[2] not in indexMap.keys():
                    indexMap[indexRow[2]] = []
                    if indexRow[1] == 0 :
                        unique = "是"
                    else:
                        unique = "否"
                    # 插入 是否唯一约束
                    indexMap[indexRow[2]].append(unique)
                indexMap[indexRow[2]].append(indexRow[4])
            table["index"] = indexMap
except Exception as e:
    raise e
finally:
    #关闭连接
    db.close()

"""
以下,导出excel,数据格式模版

tableStructureData = [{
    "table_name": "hap_template",
    "table_comment": "模版表",
    "column": [
        {
            "name": "template_id",
            "type": "序列",
            "length": "",
            "nullable": "否",
            "default": "",
            "description": "表ID,主键,供其他表做外键",
        },
    ],
    "index":{
        "amdm_asset_locations_u1":[
            "location_name",
            "tenant_id",
        ]
    }
}]
"""
# 创建一个workbook 设置编码
workbook = xlwt.Workbook(encoding = 'utf-8')
tall_style = xlwt.easyxf('font:height 300;') # 36pt,类型小初的字号
# 设置字体
font = xlwt.Font()
# 比如设置字体加粗
font.bold = True
# 设置超链接字体
linkFont = xlwt.Font()
linkFont.underline = True
linkFont.colour_index = 4
# 边框
borders = xlwt.Borders()
borders.left_colour = 0x40
# 设置虚线,其他类似
borders.top = xlwt.Borders.THIN
borders.bottom = xlwt.Borders.THIN
borders.left = xlwt.Borders.THIN
borders.right = xlwt.Borders.THIN

# 准备三种背景颜色的style
# 背景色--无
style = xlwt.XFStyle()
style.borders = borders
# 背景色--黄色
patternYellow = xlwt.Pattern()
patternYellow.pattern = xlwt.Pattern.SOLID_PATTERN
patternYellow.pattern_fore_colour = 5
styleYellow = xlwt.XFStyle()
styleYellow.pattern = patternYellow
styleYellow.borders = borders

# 背景色--淡绿色
patternLightGreen = xlwt.Pattern()
patternLightGreen.pattern = xlwt.Pattern.SOLID_PATTERN
patternLightGreen.pattern_fore_colour = 42
styleLightGreen = xlwt.XFStyle()
styleLightGreen.pattern = patternLightGreen
styleLightGreen.borders = borders
styleLightGreen.font = font

# 背景色---黄色, 超链接字体
linkStyleYellow = xlwt.XFStyle()
linkStyleYellow.pattern = patternYellow
linkStyleYellow.borders = borders
linkStyleYellow.font = linkFont

# 背景色---无, 超链接字体
linkStyle = xlwt.XFStyle()
linkStyle.borders = borders
linkStyle.font = linkFont


worksheet_0 = workbook.add_sheet("表清单")

# 第0行
worksheet_0.row(0).set_style(tall_style)
worksheet_0.write(0, 0, '表名', styleLightGreen)
worksheet_0.write(0, 1, '描述', styleLightGreen)
worksheet_0.write(0, 2, '备注', styleLightGreen)
worksheet_0.col(0).width = 8500
worksheet_0.col(1).width = 8500
worksheet_0.col(2).width = 12000

for tableStructure in tableStructureData :
    # 编写清单
    worksheet_0.row(tableStructureData.index(tableStructure)+1).set_style(tall_style)
    worksheet_0.write(tableStructureData.index(tableStructure)+1, 0, tableStructure["table_name"], styleYellow)
    # 写入超链接
    link = 'HYPERLINK("#'+tableStructure["table_comment"].replace("/", "")+'!B1";"'+tableStructure["table_comment"]+'")'
    formula = xlwt.Formula(link)
    worksheet_0.write(tableStructureData.index(tableStructure)+1, 1, formula, linkStyleYellow)
    worksheet_0.write(tableStructureData.index(tableStructure)+1, 2, "", style)
    # 创建一个worksheet
    worksheet = workbook.add_sheet(tableStructure["table_comment"].replace("/", ""))
    # 设置单元格宽度
    worksheet.col(0).width = 4200
    worksheet.col(1).width = 4200
    worksheet.col(2).width = 3000
    worksheet.col(3).width = 3000
    worksheet.col(4).width = 3000
    worksheet.col(5).width = 12000

    # 第 0 行
    # 设置高度
    worksheet.row(0).set_style(tall_style)
    worksheet.write(0, 0, '表名/描述', styleLightGreen)
    worksheet.write_merge(0, 0, 1, 2, tableStructure["table_name"], styleYellow)
    worksheet.write_merge(0, 0, 3, 5, tableStructure["table_comment"], style)
    link = 'HYPERLINK("#表清单!B1";"->返回表清单")'
    formula = xlwt.Formula(link)
    worksheet.write(0, 6, formula, linkStyle)
    # 第 1 行
    worksheet.row(1).set_style(tall_style)
    worksheet.write(1, 0, '开发简要设计', styleLightGreen)
    worksheet.write_merge(1, 1, 1, 5, "", style)

    # 第 2 行
    worksheet.row(2).set_style(tall_style)
    worksheet.write(2, 0, '数据量估算', styleLightGreen)
    worksheet.write_merge(2, 2, 1, 5, "", style)

    # 第 3 行
    worksheet.row(3).set_style(tall_style)
    worksheet.write(3, 0, '字段名', styleLightGreen)
    worksheet.write(3, 1, '类型', styleLightGreen)
    worksheet.write(3, 2, '长度', styleLightGreen)
    worksheet.write(3, 3, '允许空值', styleLightGreen)
    worksheet.write(3, 4, '默认值', styleLightGreen)
    worksheet.write(3, 5, '描述', styleLightGreen)

    # 第 4 行之后 -- 循环输出字段内容
    inx = 4
    for column in tableStructure["column"] :
        worksheet.row(inx).set_style(tall_style)
        worksheet.write(inx, 0, column["name"], styleYellow)
        worksheet.write(inx, 1, column["type"], styleYellow)
        worksheet.write(inx, 2, column["length"], style)
        worksheet.write(inx, 3, column["nullable"], styleYellow)
        worksheet.write(inx, 4, column["default"], style)
        worksheet.write(inx, 5, column["description"], style)
        inx += 1
    # 输出索引
    if "index" in tableStructure.keys() :
        worksheet.row(inx).set_style(tall_style)
        worksheet.write(inx, 0, "索引名称", styleLightGreen)
        worksheet.write(inx, 1, "唯一", styleLightGreen)
        worksheet.write(inx, 2, "字段1", styleLightGreen)
        worksheet.write(inx, 3, "字段2", styleLightGreen)
        worksheet.write(inx, 4, "字段3", styleLightGreen)
        worksheet.write(inx, 5, "更多", styleLightGreen)
        inx += 1
        for k, v  in tableStructure["index"].items() :
            worksheet.row(inx).set_style(tall_style)
            # 索引名称
            worksheet.write(inx, 0, k, styleYellow)
            for inxColName in v:
                moreName = ""
                #字段
                if(v.index(inxColName)+1 < 5) :
                    worksheet.write(inx, v.index(inxColName)+1, inxColName, style)
                else:
                    if len(v) == v.index(inxColName)+1:
                        # 最后一个,写入excel
                        worksheet.write(inx, v.index(inxColName)+1, moreName, style)
                    elif moreName:
                        moreName = moreName + "," + inxColName
                    else:
                        moreName = inxColName

            inx += 1


# 保存
workbook.save('表设计文档('+export_db_scheme+').xls')

你可能感兴趣的:(python导出excel-表结构文档生成)