python实现sqlserver表导出为excel
文章目录
- 前言
- 一、将sqlserver导出为excel
- 二、当表中数据量巨大时
- 三、加入定时器
- 四、打包成zip压缩包
- 五、删除某一目录下的所有文件
- 六、完整代码实例
- 七、Python打包EXE
- 八、openpyxl.utils.exceptions.IllegalCharacterError问题
- 九、解决中文乱码问题
前言
使用python完成将sqlserver数据库中的表导出为excel,并将文件打包成zip格式压缩包,添加定时器功能,实现每日十点定时生成文件并打包
一、将sqlserver导出为excel
# -*- coding: utf-8 -*-
from cgi import print_arguments
from datetime import datetime
import pymssql #引入pymssql模块
import xlwt #引入xlwt模块
import os
import random# current runng file path
# os.path.abspath() 是 os 模块当中的一个函数,这个函数接收一个 path 路径对象,返回 path 标准化的绝对路径。current_dir==e:\code\Python\newExcel\
current_dir = os.path.abspath(os.path.dirname(__file__))+"\\newExcel"+"\\"
connect = pymssql.connect('192.168.1.1:1433', 'haha', '123', 'test',charset="utf8") #服务器名,端口,账户,密码,数据库名def export_excel():if connect:print("连接成功!")cursor = connect.cursor() #创建一个游标对象,python里的sql语句都要通过cursor来执行sql = "select name from sysobjects where xtype='U'" #获取数据库中所有的表cursor.execute(sql) #执行sql语句responses = cursor.fetchall()for response in responses:res=''.join(response) # res为数据表的名名称 字符串形式cursor.execute('select * FROM [%s] where 1=1'%res) #对单个表进行处理,获取表中内容fields = [field[0] for field in cursor.description] # 获取所有字段名all_data = cursor.fetchall() # 所有数据aa=datetime.now().strftime('%Y-%m-%d')# 写入excelbook = xlwt.Workbook()sheet = book.add_sheet('sheet1')for col,field in enumerate(fields):sheet.write(0,col,field)row = 1for data in all_data:for col,field in enumerate(data):sheet.write(row,col,field)row += 1book.save(current_dir+res+"_"+"%s" % aa+"_"+str(random.random())+".xls")print("Export to excel success!")if __name__ == '__main__':# export data from SQL serverexport_excel()# close database connectionconnect.close()
二、当表中数据量巨大时
对于表中数据量巨大时(内容超过一百万条数据时,使用多个sheet)
使用xlwt 库大概一个sheet中能导出五六万条数据?,而openpyxl大概一百万,当数据量巨大时,需要多个sheet
# 导出excel函数
def export_excel():if connect:print("连接成功!")cursor = connect.cursor() #创建一个游标对象,python里的sql语句都要通过cursor来执行sql = "select name from sysobjects where xtype='U'"cursor.execute(sql) #执行sql语句responses = cursor.fetchall()maxrow=0for response in responses:res=''.join(response)#获取每一个表的行数cursor.execute('select count(*) as rows from [%s]'%res)rows = cursor.fetchall()# print(type(rows[0][0]))if maxrow<rows[0][0]:maxrow = rows[0][0]for response in responses:res=''.join(response)print('表名:'+res)cursor.execute('select * FROM [%s] where 1=1'%res)fields = [field[0] for field in cursor.description] # 获取所有字段名all_data = cursor.fetchall() # 所有数据curtime=datetime.datetime.now().strftime('%Y-%m-%d')r=int(maxrow/1000000) #每一个sheet可以容纳一百万条数据# 写入excelbook = openpyxl.Workbook()sheet=[]for i in range(r+1):sheet.append(book.create_sheet(index=i))# print(sheet[i])for col,field in enumerate(fields):for i in range(r+1):sheet[i].cell(1,col+1,field) #row的第一行为名称,从第二行起才是值row = 2i=0for data in all_data:for col,field in enumerate(data):field=ILLEGAL_CHARACTERS_RE.sub(r'', str(field))try:field=field.encode('latin1').decode('gbk')except:print(field)#field=field.encode('utf8','ignore').decode('gbk')sheet[i].cell(row,col+1,field) row += 1if row>=1000002:i+=1row=2book.save(current_dir+'/'+res+"_"+"%s" % curtime+"_"+".xls")#open(current_dir+'/'+res+"_"+"%s" % curtime+"_"+".xls","r",encoding='GBK')print("Export to excel success!")if __name__ == '__main__':# export data from SQL serverexport_excel()# close database connectionconnect.close()
三、加入定时器
代码如下(示例):
import datetime
import threading
marktime=" 9:24:20" #启动的时间,最前面有个空格不要删除# 运行函数
def func():# 在这里加你的函数即可,86400是3600*24 print("haha")timer = threading.Timer(86400, func)timer.start()
# preFun预处理函数
def preFun():now_time = datetime.datetime.now()marktimes = datetime.datetime.strptime(str(now_time.date()) + marktime, "%Y-%m-%d %H:%M:%S")if (now_time <= marktimes):next_time = marktimesprint("今日" + marktime + '执行代码')else:# 明日启动next_time = now_time + datetime.timedelta(days=+1)print("明日" + marktime + '执行代码')next_year = next_time.date().yearnext_month = next_time.date().monthnext_day = next_time.date().daynext_time = datetime.datetime.strptime(str(next_year) +"-" + str(next_month) +"-" + str(next_day) + marktime,"%Y-%m-%d %H:%M:%S")timer_start_time = (next_time - now_time).total_seconds()return timer_start_time
def main():timer_start_time=preFun()timer = threading.Timer(timer_start_time, func)timer.start()print('冷启动后启动func的时间',timer_start_time)pass
if __name__ == '__main__':main()
四、打包成zip压缩包
满足将导出的excel文件打包成zip的需求
#打包目录为zip文件(未压缩)
#filedir为文件目录
def zip_file(filedir):"""压缩文件夹至同名zip文件"""file_news = filedir + '.zip'z = zipfile.ZipFile(file_news,'w',zipfile.ZIP_DEFLATED) #参数一:文件夹名for dirpath, dirnames, filenames in os.walk(filedir):fpath = dirpath.replace(filedir,'') #这一句很重要,不replace的话,就从根目录开始复制fpath = fpath and fpath + os.sep or ''#这句话理解我也点郁闷,实现当前文件夹以及包含的所有文件的压缩for filename in filenames:z.write(os.path.join(dirpath, filename),fpath+filename)z.close()
五、删除某一目录下的所有文件
需求为每日定时讲数据表导出为excel,因此需要将昨日产生的excel删除
def del_files(path_file):ls = os.listdir(path_file)for i in ls:f_path = os.path.join(path_file, i)# 判断是否是一个目录,若是,则递归删除if os.path.isdir(f_path):del_files(f_path)else:os.remove(f_path)
六、完整代码实例
# -*- coding: utf-8 -*-
from base64 import encode
from datetime import datetime
from openpyxl.cell.cell import ILLEGAL_CHARACTERS_RE
import pymssql #引入pymssql模块
import openpyxl
import os
import datetime
import threading
import zipfile#几点开始执行 有个空格不要删除
marktime=" 22:00:00"
current_dir = 'E:/apps/temp'
connect = pymssql.connect('127.0.0.1:1466', 'sa', 'xxx', 'xxx',charset="utf8") #服务器名,端口,账户,密码,数据库名# 运行函数
def func():if os.path.exists(current_dir):print("临时目录已经存在")else:os.mkdir(current_dir)# 删除临时目录下的所有文件del_files(current_dir)# 生成excle的函数export_excel()# 将生成的excel压缩成zipzip_file(current_dir) #指定要压缩的文件夹路径#86400是3600*24 Timer第一个参数指定时间(秒)timer = threading.Timer(86400, func) timer.start()# preFun预处理函数
def preFun():now_time = datetime.datetime.now()marktimes = datetime.datetime.strptime(str(now_time.date()) + marktime, "%Y-%m-%d %H:%M:%S")if (now_time <= marktimes):next_time = marktimesprint("今日" + marktime + '执行代码')else:# 明日启动next_time = now_time + datetime.timedelta(days=+1)print("明日" + marktime + '执行代码')next_year = next_time.date().yearnext_month = next_time.date().monthnext_day = next_time.date().daynext_time = datetime.datetime.strptime(str(next_year) +"-" + str(next_month) +"-" + str(next_day) + marktime,"%Y-%m-%d %H:%M:%S")timer_start_time = (next_time - now_time).total_seconds()return timer_start_time# 导出excel函数
def export_excel():if connect:print("连接成功!")cursor = connect.cursor() #创建一个游标对象,python里的sql语句都要通过cursor来执行sql = "select name from sysobjects where xtype='U'"cursor.execute(sql) #执行sql语句responses = cursor.fetchall()maxrow=0for response in responses:res=''.join(response)#获取每一个表的行数cursor.execute('select count(*) as rows from [%s]'%res)rows = cursor.fetchall()# print(type(rows[0][0]))if maxrow<rows[0][0]:maxrow = rows[0][0]for response in responses:res=''.join(response)print('表名:'+res)cursor.execute('select * FROM [%s] where 1=1'%res)fields = [field[0] for field in cursor.description] # 获取所有字段名all_data = cursor.fetchall() # 所有数据curtime=datetime.datetime.now().strftime('%Y-%m-%d')r=int(maxrow/1000000) #每一个sheet可以容纳一百万条数据# 写入excelbook = openpyxl.Workbook()sheet=[]for i in range(r+1):sheet.append(book.create_sheet(index=i))# print(sheet[i])for col,field in enumerate(fields):for i in range(r+1):sheet[i].cell(1,col+1,field) #row的第一行为名称,从第二行起才是值row = 2i=0for data in all_data:for col,field in enumerate(data):field=ILLEGAL_CHARACTERS_RE.sub(r'', str(field))try:field=field.encode('latin1').decode('gbk')except:print(field)#field=field.encode('utf8','ignore').decode('gbk')sheet[i].cell(row,col+1,field) row += 1if row>=1000002:i+=1row=2book.save(current_dir+'/'+res+"_"+"%s" % curtime+"_"+".xls")#open(current_dir+'/'+res+"_"+"%s" % curtime+"_"+".xls","r",encoding='GBK')print("Export to excel success!")#打包目录为zip文件(未压缩)
def zip_file(filedir):"""压缩文件夹至同名zip文件"""file_news = filedir + '.zip'z = zipfile.ZipFile(file_news,'w',zipfile.ZIP_DEFLATED) #参数一:文件夹名for dirpath, dirnames, filenames in os.walk(filedir):fpath = dirpath.replace(filedir,'') #这一句很重要,不replace的话,就从根目录开始复制fpath = fpath and fpath + os.sep or ''#这句话理解我也点郁闷,实现当前文件夹以及包含的所有文件的压缩for filename in filenames:z.write(os.path.join(dirpath, filename),fpath+filename)z.close()#删除某一目录下的所有文件
def del_files(path_file):ls = os.listdir(path_file)for i in ls:f_path = os.path.join(path_file, i)# 判断是否是一个目录,若是,则递归删除if os.path.isdir(f_path):del_files(f_path)else:os.remove(f_path)def main():timer_start_time=preFun()timer = threading.Timer(timer_start_time, func)timer.start()print('冷启动后启动func的时间',timer_start_time)# close database connection# connect.close() passif __name__ == '__main__':main()
七、Python打包EXE
- 首先安装pyinstaller,使用安装命令:pip3 install pyinstaller
- cmd切换到想要打包的py文件所在目录,执行命令:pyinstaller-F 文件名.py
- 执行完毕之后,会生成几个文件夹,如下图所示。
pyinstaller打包exe文件及过程中 no module named 问题处理
pyinstaller -F test.py --hidden-import openpyxl
八、openpyxl.utils.exceptions.IllegalCharacterError问题
数据写入时excel中含有异常字符报错
解决方法:
from openpyxl.cell.cell import ILLEGAL_CHARACTERS_RE
s = '谢谢你\x00\x00\x00\x00\t' # \x00为非法字符
print(s.encode())
s = ILLEGAL_CHARACTERS_RE.sub(r'', s)
print(s.encode())
输出结果:
b'\xe8\xb0\xa2\xe8\xb0\xa2\xe4\xbd\xa0\x00\x00\x00\x00'
b'\xe8\xb0\xa2\xe8\xb0\xa2\xe4\xbd\xa0'
可见\x00被处理掉了
九、解决中文乱码问题
在sqlserver数据库中输入
SELECT COLLATIONPROPERTY('Chinese_PRC_Stroke_CI_AI_KS_WS', 'CodePage')
查看结果为936
936 简体中文GBK
950 繁体中文BIG5
437 美国/加拿大英语
932 日文
949 韩文
866 俄文
65001 unicode UFT-8
查看表可知使用的编码方式为GBK
因此修改开头连接出的charset=“GBK”
connect = pymssql.connect('192.168.1.1:1433', 'haha', '123', 'test',charset="GBK") #服务器名,端口,账户,密码,数据库名
导出结果显示正常!
解决UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xb9 in position x: illegal multibyte sequence问题
第一种解决方法,增加encoding=‘UTF-8’:
FILE_OBJECT= open( 'train.txt','r', encoding='UTF-8' )
第二种方法,二进制读取:
FILE_OBJECT= open( 'train.txt', 'rb' )
因此将field=ILLEGAL_CHARACTERS_RE.sub(rb’', str(field)) 改为rb
中文乱码问题补充醒
(1) 问题描述:为了更好地展示数据,Excel格式的数据文件往往比文本文件更具有优势,但是具体到python中,该如何导出数据到Excel呢?如果碰到需要导出大量数据又该如何操作呢? 本文主要解决以 ... (1) 问题描述:为了更好地展示数据,Excel格式的数据文件往往比文本文件更具有优势,但是具体到python中,该如何导出数据到Excel呢?如果碰到需要导出大量数据又该如何操作呢? 本文主要解决以 ... 如何使用python将大量数据导出到Excel中的小技巧 (1) 问题描述:为了更好地展示数据,Excel格式的数据文件往往比文本文件更具有优势,但是具体到python中,该如何导出数据到Excel呢 ... 怎么在python中将大量数据导出到Excel文件 发布时间:2021-01-16 11:09:40 来源:亿速云 阅读:76 作者:Leah 这期内容当中小编将会给大家带来有关怎么在python中将 ... 如何使用python将大量数据导出到Excel中的小技巧 (1) 问题描述:为了更好地展示数据,Excel格式的数据文件往往比文本文件更具有优势,但是具体到python中,该如何导出数据到Excel呢 ... 如何使用python将大量数据导出到Excel中的小技巧 (1) 问题描述:为了更好地展示数据,Excel格式的数据文件往往比文本文件更具有优势,但是具体到python中,该如何导出数据到Excel呢 ... 如何使用python将大量数据导出到Excel中的小技巧 (1) 问题描述:为了更好地展示数据,Excel格式的数据文件往往比文本文件更具有优势,但是具体到python中,该如何导出数据到Excel呢 ... 使用python将大量数据导出到Excel中的小技巧分享 今天小编就为大家分享一篇使用python将大量数据导出到Excel中的小技巧心得,具有很好的参考价值,希望对大家有所帮助.一起跟随小编过来看看 ... 如何使用python将大量数据导出到Excel中的小技巧 (1) 问题描述:为了更好地展示数据,Excel格式的数据文件往往比文本文件更具有优势,但是具体到python中,该如何导出数据到Excel呢 ...python实现sqlserver表导出为excel相关推荐
最新文章
热门文章