python 链接mysql数据库查询数据导出成表格,自动将数据库字段名写入表格列名-全查询内存后,进行写入
# -*- ecoding: utf-8 -*-
# @ModuleName: test
# @Funcation:
# @Author: darling
# @Time: 2022-07-28 15:29
import datetime
import os
import re
import sys
import time
import openpyxl
import pymysql
from loguru import logger
global sheet_nums
sheet_nums = 0
def client_database(sql):
# 打开数据库连接
db = pymysql.connect(host="127.0.0.1", user="root", password="123", db="test",
port=3306)
# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()
# 使用 execute() 方法执行 SQL 查询
cursor.execute(sql)
# 使用 fetchall() 方法获取s所有数据.
datas = cursor.fetchall()
# 表头字段名
fileds = [filed[0] for filed in cursor.description]
db.close()
return fileds, list(datas)
def check_file_type(f_path):
txt = re.compile(r'\.xlsx$')
if txt.search(f_path) is None:
exit_sys('文件格式格式不正确,只允许xlsx文件')
if fileIsOpen(f_path):
logger.info('============={}:文件被占用,无法写入,请关闭文件=========', f_path)
exit_sys('文件被占用,请关闭 ' + f_path)
def exit_sys(msg):
logger.info(msg)
logger.info('程序退出··· ···')
time.sleep(3)
sys.exit()
# 判定文件是否打开
def fileIsOpen(filepath):
filef = os.path.split(filepath) # 文件路径和文件名拆开
excelname = filef[-1]
excelpath = filef[0]
hidefilename = excelpath + r"/~$" + excelname # 拼接出隐藏文件的文件路径
if os.path.exists(hidefilename):
return True
else:
return False
def exists_file(file_name):
return os.path.exists(file_name)
# 判断文件是否存在
def sheet_method(file_path, add_sheet, sheet_num=1):
if not exists_file(file_path):
wk = openpyxl.Workbook()
else:
wk = openpyxl.load_workbook(file_path)
index = sheet_num - 1
add_sheet = add_sheet + str(sheet_num)
if add_sheet in wk.sheetnames: # 表格如果已经存在,那就删除,在重新创建,清空历史数据
del wk[add_sheet]
if 'Sheet' in wk.sheetnames: # 将默认的sheet表格删除
del wk['Sheet']
wk.create_sheet(title=add_sheet, index=index)
wk.save(file_path)
# 保存数据到多个文件
def save_excel_to_file(fileds, datas, file_name, sheet_name, sheet_num=0):
logger.info('我进来了save方法')
global sheet_nums
sheet_nums += 1
sheet_num = sheet_nums
file_name = file_name.replace(f'-{sheet_num - 1}.xlsx', f'-{sheet_num}.xlsx')
# 判断文件是否存在
sheet_method(file_name, sheet_name, sheet_num)
wb = openpyxl.load_workbook(file_name) # 打开文件
ws = wb.active
sheets = False
logger.info('总数据:{} 行', len(datas))
# 判断数据内容是否超过100W,超过100W 剩下的写入另外一个表格
if len(datas) > 1000:
databbs = datas[:1000]
del datas[0:1000]
sheets = True
else:
databbs = datas
# 写入表格第一行表头
i = 1
leng = len(fileds)
while i <= leng:
ws.cell(1, i, fileds[i - 1])
i = i + 1
# 写入表格内容
j = 1
# 循环行
for data in databbs:
di = 1
j = j + 1
# 循环列
for k in range(len(data)):
ws.cell(j, di, data[k])
di = di + 1
wb.save(file_name)
logger.info('保存文件{}', file_name)
if sheets:
save_excel_to_file(fileds, datas, file_name, sheet_name)
# 保存数据到一个文件,多个sheet页签,sheet页越多越慢
def save_excel_to_sheets(fileds, datas, file_name, sheet_name, sheet_num=0):
logger.info('我进来了save方法')
global sheet_nums
sheet_nums += 1
sheet_num = sheet_nums
# file_name = file_name.replace(f'-{sheet_num - 1}.xlsx', f'-{sheet_num}.xlsx')
# 判断文件是否存在
sheet_method(file_name, sheet_name, sheet_num)
wb = openpyxl.load_workbook(file_name) # 打开文件
ws = wb[sheet_name + str(sheet_num)]
sheets = False
logger.info('总数据:{} 行', len(datas))
# 判断数据内容是否超过100W,超过100W 剩下的写入另外一个表格
if len(datas) > 1000:
databbs = datas[:1000]
del datas[0:1000]
sheets = True
else:
databbs = datas
# 写入表格第一行表头
i = 1
leng = len(fileds)
while i <= leng:
ws.cell(1, i, fileds[i - 1])
i = i + 1
# 写入表格内容
j = 1
# 循环行
for data in databbs:
di = 1
j = j + 1
# 循环列
for k in range(len(data)):
ws.cell(j, di, data[k])
di = di + 1
wb.save(file_name)
logger.info('保存文件{}', file_name)
if sheets:
save_excel_to_sheets(fileds, datas, file_name, sheet_name)
def query_sql_to_excel(sql):
# 生成文件名
fileName = './' + str(datetime.datetime.now().strftime("%Y-%m-%d-%H%M%S")) + '-1.xlsx'
# check_file_type(f_path=fileName)
sql_res = client_database(sql)
logger.info('执行SQL完毕')
save_excel_to_sheets(fileds=sql_res[0], datas=sql_res[1], file_name=fileName, sheet_name='Sheet')
if __name__ == '__main__':
sql = """ SELECT id as '唯一id',`name` as '名称',phone as '电话',address as '地址' FROM people_infomation """
query_sql_to_excel(sql)
# todo 想想方法使用真分页实现,可以减小客户端内存占用噢,还可以使用多线程执行噢
惜秦皇汉武,略输文采;唐宗宋祖,稍逊风骚。
一代天骄,成吉思汗,只识弯弓射大雕。
俱往矣,数风流人物,还看今朝