目录

一、excel文件内容如下:

二、生成如下sql:

三、 思路:

1.设计界面

2.界面分模块设计

2.1 模块一(数据库选择)

点击选择按钮会触发command后面的函数,同时会相应的返回value值

2.2 模块一(Excel文件)

2.3 模块一(字段列表)

2.4 模块一(建表sql预览)

3.具体函数

3.1 xlsx文件转换成xls文件

3.2  添加文件目录

3.3  获取sheet、行列数

3.4  获取表名称

3.5 获取字段、类型、注释

3.6 根据sheet、列数获取具体数据

3.7 保存建表文件

3.8 弹窗模块

四、 将代码打包成exe应用

五、全部代码

六、打包好的应用


一、excel文件内容如下:

二、生成如下sql:

三、 思路:

利用python的xlrd包来解析excel(xlrd包只支持xls格式文件)

利用python的tkinter包来设计GUI界面

1.设计界面

界面分成4部分,如下图

界面代码如下

#设置界面def SetGUI(self):self.init_window_name.title("Excel文件创建建表sql文件")self.init_window_name.geometry('1300x750')#self.init_window_name.overrideredirect(1) # 隐藏标题栏 最大化最小化按钮#self.init_window_name.attributes("-toolwindow", 2) # 去掉窗口最大化最小化按钮,只保留关闭self.init_window_name.resizable(0,0)# 禁止拉伸窗口##button_filename=add_Excel_file()#数据库选择部分self.select_database_labelframe = tk.LabelFrame(self.init_window_name,width=1280, height=53,text="数据库选择")self.select_database_labelframe.place(x=10,y=2)self.hive_Radiobutton = Radiobutton(self.select_database_labelframe,text="hive数据库",variable=self.get_select_datebase,value='hive',command=self.select_hive_database)self.hive_Radiobutton.place(x=50,y=0)self.pg_Radiobutton = Radiobutton(self.select_database_labelframe,text="pg数据库",variable=self.get_select_datebase,value='pg',command=self.select_pg_database)self.pg_Radiobutton.place(x=200,y=0)self.tip_label = tk.Label(self.select_database_labelframe,width=80,height=1,fg="red", bg="yellow", font=("微软雅黑", 12,"bold"), text="提示:选择的Excel文件最好是xls格式的。如果是xlsx格式的,按钮响应时间有点慢!!!")self.tip_label.place(x=420,y=0)#self.get_datebase_hive.set('hive')#self.pg_Radiobutton.select() #默认hive_Radiobutton这个按钮被选中#print(self.hive_Radiobutton.get())#文件编辑部分labelframe = tk.LabelFrame(self.init_window_name,width=680, height=300, text="Excel文件")#labelframe.pack()labelframe.place(x=10,y=60)self.Excel_label = tk.Label(labelframe,width=10,height=1,fg='red', font=("微软雅黑", 10), text="目录路径:")self.Excel_label.place(x=0,y=2)self.Excel_path = tk.Entry(labelframe, width=60, textvariable=self.get_value)self.Excel_path.place(x=80,y=5)self.Excel_file = tk.Button(labelframe,width=23,height=1,fg='blue', text="选择Excel文件(只支持xls格式)",command=self.add_Excel_file)self.Excel_file.place(x=505,y=5)#表名self.start_row_label_location = tk.Label(labelframe,width=22,height=1,fg='red', font=("微软雅黑", 13),text="请填写表名位置信息", anchor="sw")self.start_row_label_location.place(x=0,y=38)self.start_row_label = tk.Label(labelframe,width=22,height=1, text="表名开始行(填写数字):")self.start_row_label.place(x=0,y=70)self.start_row = tk.Entry(labelframe, width=15, textvariable=self.get_start_row_value)self.start_row.place(x=160,y=70)self.end_row_label = tk.Label(labelframe,width=22,height=1, text="表名结束行(填写数字):")self.end_row_label.place(x=0,y=100)self.end_row = tk.Entry(labelframe, width=15, textvariable=self.get_end_row_value)self.end_row.place(x=160,y=100)self.start_col_label = tk.Label(labelframe,width=22,height=1, text="表名开始列(填写字母):")self.start_col_label.place(x=0,y=130)self.start_col = tk.Entry(labelframe, width=15, textvariable=self.get_start_col_value)self.start_col.place(x=160,y=130)self.end_col_label = tk.Label(labelframe,width=22,height=1, text="表名结束列(填写字母):")self.end_col_label.place(x=0,y=160)self.end_col = tk.Entry(labelframe, width=15, textvariable=self.get_end_col_value)self.end_col.place(x=160,y=160)#表字段self.start_row_label_field_location = tk.Label(labelframe,width=28,height=1,fg='red', font=("微软雅黑", 13),text="请填写表字段、注释、类型位置信息", anchor="sw")self.start_row_label_field_location.place(x=320,y=38)self.start_row_label_field = tk.Label(labelframe,width=24,height=1, text="表字段开始行(填写数字):")self.start_row_label_field.place(x=320,y=70)self.start_row_field = tk.Entry(labelframe, width=15, textvariable=self.get_start_row_field_value)self.start_row_field.place(x=494,y=70)self.end_row_label_field = tk.Label(labelframe,width=24,height=1, text="表字段结束行(填写数字):")self.end_row_label_field.place(x=320,y=100)self.end_row_field = tk.Entry(labelframe, width=15, textvariable=self.get_end_row_field_value)self.end_row_field.place(x=494,y=100)self.start_col_label_field = tk.Label(labelframe,width=24,height=1, text="表字段开始列(填写字母):")self.start_col_label_field.place(x=320,y=130)self.start_col_field = tk.Entry(labelframe, width=15, textvariable=self.get_start_col_field_value)self.start_col_field.place(x=494,y=130)self.end_col_label_field = tk.Label(labelframe,width=24,height=1, text="表字段结束列(填写字母):")self.end_col_label_field.place(x=320,y=160)self.end_col_field = tk.Entry(labelframe, width=15, textvariable=self.get_end_col_field_value)self.end_col_field.place(x=494,y=160)#输入sheet数字 页面改成下拉选择框self.sheet_label= tk.Label(labelframe,width=24,height=2,fg='green', text="请选择Excel中sheet", font=("微软雅黑", 14), anchor="sw")self.sheet_label.place(x=10,y=183)#self.sheet_value = tk.Entry(labelframe, width=15, textvariable=self.get_sheet_value)#self.sheet_value.place(x=10,y=245)self.sheet_value=ttk.Combobox(labelframe,textvariable=self.get_sheet_value)self.sheet_value.place(x=15,y=240)#self.sheet_value['value'] = ('下拉选项1', '下拉选项2', '下拉选项3', '下拉选项4')#self.sheet_value.current(0)#填写位置信息例子按钮self.Excel_field = tk.Button(labelframe,width=40,height=3,fg='blue', text="填写前,一定要点击我,查看位置信息格式!!!",command=self.Open_image)self.Excel_field.place(x=240,y=200)#查找按钮self.Excel_field = tk.Button(labelframe,width=17,height=3,fg='blue', text="查找表名、字段、注释",command=self.get_start_end_row_col_value)self.Excel_field.place(x=540,y=200)#保存文件按钮self.save_sql = tk.Button(labelframe,width=5,height=7,fg='blue', text="保存建表文件",wraplength=2,command=self.display_messagebox)self.save_sql.place(x=615,y=61)#字段显示列表LabelFrameself.field_labelframe = tk.LabelFrame(self.init_window_name,width=680, height=375,text="字段列表")self.field_labelframe.place(x=10,y=370)# 定义树形结构与滚动条self.field_tree = ttk.Treeview(self.field_labelframe, show="headings", columns=("a", "b", "c", "d"), height=16)self.vbar = Scrollbar(self.field_labelframe, orient='vertical', command=self.field_tree.yview,activerelief='ridge')#self.vbar.pack(side = tk.RIGHT, fill = tk.Y)self.field_tree.configure(yscrollcommand=self.vbar.set)# 表格的标题self.field_tree.column("a", width=100, anchor="center")self.field_tree.column("b", width=250, anchor="center")self.field_tree.column("c", width=150, anchor="center")self.field_tree.column("d", width=150, anchor="center")self.field_tree.heading("a", text="序号")self.field_tree.heading("b", text="字段名")self.field_tree.heading("c", text="字段类型",)self.field_tree.heading("d", text="注释")self.field_tree.place(x=0,y=3)# self.field_tree.bind("<Double-1>", self.onDBClick)self.vbar.place(x=653,y=3,relheight=0.99) #滚动条长度,取值在0-1之间#建表sql预览模块self.view_sql_labelframe = tk.LabelFrame(self.init_window_name,width=590, height=685,text="建表SQL预览")self.view_sql_labelframe.place(x=700,y=60)self.view_sql_Text = tk.Text(self.view_sql_labelframe,height=50, width=80,fg='red')self.view_sql_Text.place(x=0,y=5)self.view_sql_vbar = Scrollbar(self.view_sql_labelframe, orient='vertical', command=self.view_sql_Text.yview,activerelief='ridge')self.view_sql_Text.configure(yscrollcommand=self.view_sql_vbar.set)self.view_sql_vbar.place(x=565,y=5,relheight=0.99) #滚动条长度,取值在0-1之间

2.界面分模块设计

2.1 模块一(数据库选择)

代码如下:

#数据库选择部分self.select_database_labelframe = tk.LabelFrame(self.init_window_name,width=1280, height=53,text="数据库选择")self.select_database_labelframe.place(x=10,y=2)self.hive_Radiobutton = Radiobutton(self.select_database_labelframe,text="hive数据库",variable=self.get_select_datebase,value='hive',command=self.select_hive_database)self.hive_Radiobutton.place(x=50,y=0)self.pg_Radiobutton = Radiobutton(self.select_database_labelframe,text="pg数据库",variable=self.get_select_datebase,value='pg',command=self.select_pg_database)self.pg_Radiobutton.place(x=200,y=0)self.tip_label = tk.Label(self.select_database_labelframe,width=80,height=1,fg="red", bg="yellow", font=("微软雅黑", 12,"bold"), text="提示:选择的Excel文件最好是xls格式的。如果是xlsx格式的,按钮响应时间有点慢!!!")self.tip_label.place(x=420,y=0)

点击选择按钮会触发command后面的函数,同时会相应的返回value值

2.2 模块一(Excel文件)

点击相应的按钮会触发command后面的函数

代码如下:

#excel文件模块#文件编辑部分labelframe = tk.LabelFrame(self.init_window_name,width=680, height=300, text="Excel文件")#labelframe.pack()labelframe.place(x=10,y=60)self.Excel_label = tk.Label(labelframe,width=10,height=1,fg='red', font=("微软雅黑", 10), text="目录路径:")self.Excel_label.place(x=0,y=2)self.Excel_path = tk.Entry(labelframe, width=60, textvariable=self.get_value)self.Excel_path.place(x=80,y=5)self.Excel_file = tk.Button(labelframe,width=23,height=1,fg='blue', text="选择Excel文件(只支持xls格式)",command=self.add_Excel_file)self.Excel_file.place(x=505,y=5)#表名self.start_row_label_location = tk.Label(labelframe,width=22,height=1,fg='red', font=("微软雅黑", 13),text="请填写表名位置信息", anchor="sw")self.start_row_label_location.place(x=0,y=38)self.start_row_label = tk.Label(labelframe,width=22,height=1, text="表名开始行(填写数字):")self.start_row_label.place(x=0,y=70)self.start_row = tk.Entry(labelframe, width=15, textvariable=self.get_start_row_value)self.start_row.place(x=160,y=70)self.end_row_label = tk.Label(labelframe,width=22,height=1, text="表名结束行(填写数字):")self.end_row_label.place(x=0,y=100)self.end_row = tk.Entry(labelframe, width=15, textvariable=self.get_end_row_value)self.end_row.place(x=160,y=100)self.start_col_label = tk.Label(labelframe,width=22,height=1, text="表名开始列(填写字母):")self.start_col_label.place(x=0,y=130)self.start_col = tk.Entry(labelframe, width=15, textvariable=self.get_start_col_value)self.start_col.place(x=160,y=130)self.end_col_label = tk.Label(labelframe,width=22,height=1, text="表名结束列(填写字母):")self.end_col_label.place(x=0,y=160)self.end_col = tk.Entry(labelframe, width=15, textvariable=self.get_end_col_value)self.end_col.place(x=160,y=160)#表字段self.start_row_label_field_location = tk.Label(labelframe,width=28,height=1,fg='red', font=("微软雅黑", 13),text="请填写表字段、注释、类型位置信息", anchor="sw")self.start_row_label_field_location.place(x=320,y=38)self.start_row_label_field = tk.Label(labelframe,width=24,height=1, text="表字段开始行(填写数字):")self.start_row_label_field.place(x=320,y=70)self.start_row_field = tk.Entry(labelframe, width=15, textvariable=self.get_start_row_field_value)self.start_row_field.place(x=494,y=70)self.end_row_label_field = tk.Label(labelframe,width=24,height=1, text="表字段结束行(填写数字):")self.end_row_label_field.place(x=320,y=100)self.end_row_field = tk.Entry(labelframe, width=15, textvariable=self.get_end_row_field_value)self.end_row_field.place(x=494,y=100)self.start_col_label_field = tk.Label(labelframe,width=24,height=1, text="表字段开始列(填写字母):")self.start_col_label_field.place(x=320,y=130)self.start_col_field = tk.Entry(labelframe, width=15, textvariable=self.get_start_col_field_value)self.start_col_field.place(x=494,y=130)self.end_col_label_field = tk.Label(labelframe,width=24,height=1, text="表字段结束列(填写字母):")self.end_col_label_field.place(x=320,y=160)self.end_col_field = tk.Entry(labelframe, width=15, textvariable=self.get_end_col_field_value)self.end_col_field.place(x=494,y=160)#输入sheet数字 页面改成下拉选择框self.sheet_label= tk.Label(labelframe,width=24,height=2,fg='green', text="请选择Excel中sheet", font=("微软雅黑", 14), anchor="sw")self.sheet_label.place(x=10,y=183)#self.sheet_value = tk.Entry(labelframe, width=15, textvariable=self.get_sheet_value)#self.sheet_value.place(x=10,y=245)self.sheet_value=ttk.Combobox(labelframe,textvariable=self.get_sheet_value)self.sheet_value.place(x=15,y=240)#self.sheet_value['value'] = ('下拉选项1', '下拉选项2', '下拉选项3', '下拉选项4')#self.sheet_value.current(0)#填写位置信息例子按钮self.Excel_field = tk.Button(labelframe,width=40,height=3,fg='blue', text="填写前,一定要点击我,查看位置信息格式!!!",command=self.Open_image)self.Excel_field.place(x=240,y=200)#查找按钮self.Excel_field = tk.Button(labelframe,width=17,height=3,fg='blue', text="查找表名、字段、注释",command=self.get_start_end_row_col_value)self.Excel_field.place(x=540,y=200)#保存文件按钮self.save_sql = tk.Button(labelframe,width=5,height=7,fg='blue', text="保存建表文件",wraplength=2,command=self.display_messagebox)self.save_sql.place(x=615,y=61)

2.3 模块一(字段列表)

代码如下:

#list模块#字段显示列表LabelFrameself.field_labelframe = tk.LabelFrame(self.init_window_name,width=680, height=375,text="字段列表")self.field_labelframe.place(x=10,y=370)# 定义树形结构与滚动条self.field_tree = ttk.Treeview(self.field_labelframe, show="headings", columns=("a", "b", "c", "d"), height=16)self.vbar = Scrollbar(self.field_labelframe, orient='vertical', command=self.field_tree.yview,activerelief='ridge')#self.vbar.pack(side = tk.RIGHT, fill = tk.Y)self.field_tree.configure(yscrollcommand=self.vbar.set)# 表格的标题self.field_tree.column("a", width=100, anchor="center")self.field_tree.column("b", width=250, anchor="center")self.field_tree.column("c", width=150, anchor="center")self.field_tree.column("d", width=150, anchor="center")self.field_tree.heading("a", text="序号")self.field_tree.heading("b", text="字段名")self.field_tree.heading("c", text="字段类型",)self.field_tree.heading("d", text="注释")self.field_tree.place(x=0,y=3)# self.field_tree.bind("<Double-1>", self.onDBClick)self.vbar.place(x=653,y=3,relheight=0.99) #滚动条长度,取值在0-1之间

2.4 模块一(建表sql预览)

代码如下:

#建表sql预览模块self.view_sql_labelframe = tk.LabelFrame(self.init_window_name,width=590, height=685,text="建表SQL预览")self.view_sql_labelframe.place(x=700,y=60)self.view_sql_Text = tk.Text(self.view_sql_labelframe,height=50, width=80,fg='red')self.view_sql_Text.place(x=0,y=5)self.view_sql_vbar = Scrollbar(self.view_sql_labelframe, orient='vertical', command=self.view_sql_Text.yview,activerelief='ridge')self.view_sql_Text.configure(yscrollcommand=self.view_sql_vbar.set)self.view_sql_vbar.place(x=565,y=5,relheight=0.99) #滚动条长度,取值在0-1之间

3.具体函数

3.1 xlsx文件转换成xls文件

如果输入的文件是xls格式的,就不需要转换。如果输入的文件是xlsx格式,就会在原文件目录自动复制一个临时xls文件,等用户点击“保存文件”按钮后或者关闭怎么应用之后,就会删除创建的临时xls文件。具体删除代码在:点击按钮后删除代码在“保存文件”函数中,关闭应用删除代码在main函数中。

def xlsx_to_xls(self,fname, export_name, delete_flag=False):"""将xlsx文件转化为xls文件:param fname: 传入待转换的文件路径(可传绝对路径,也可传入相对路径,都可以):param export_name: 传入转换后到哪个目录下的路径(可传绝对路径,也可传入相对路径,都可以):param delete_flag: 转换成功后,是否删除原来的xlsx的文件,默认删除 布尔类型:return:    无返回值"""excel = win32.gencache.EnsureDispatch('Excel.Application')excel.Visible = Falseexcel.DisplayAlerts = Falseabsolute_path = os.path.join(os.path.dirname(os.path.abspath(fname)), os.path.basename(fname))save_path = os.path.join(os.path.dirname(os.path.abspath(export_name)), os.path.basename(export_name))wb = excel.Workbooks.Open(absolute_path)wb.SaveAs(save_path, FileFormat=56)  # FileFormat = 51 is for .xlsx extensionwb.Close()  # FileFormat = 56 is for .xls extensionexcel.Application.Quit()if delete_flag:os.remove(absolute_path)

3.2  添加文件目录

 def add_Excel_file(self):      try:filename = tkinter.filedialog.askopenfilename(title=u'打开文件')self.clear_entry()#清空内容#清空listself.clear_tree_value(self.field_tree)#清除text内容self.clear_text_value(self.view_sql_Text)if filename!='': #如果关闭选择窗口会返回一个空值if str(os.path.splitext(filename)[-1])=='.xlsx': #如果选择的文件为xlsx文件,就需要转换成xls文件#get_value.set(filename)#print('文件名为%s'%filename)self.random_string=self.create_string_number(8)#随机生成6位字符串self.filename_dir=os.path.dirname(filename)#获取文件目录路径#print('文件为%s'%self.filename_dir)fname_path=filenameexport_name_path=self.filename_dir+str()#转换后的新xls文件名    self.filename_xls=str(os.path.splitext(filename)[0])+'_'+str(self.random_string)+'.xls'#转换函数self.xlsx_to_xls(fname=fname_path, export_name=self.filename_xls, delete_flag=False)self.get_value.set(filename) #entry标签设置内容self.file_path =self.filename_xls #获取文件路径内容,后面打开文件的路径是用这个路径self.delete_xlsx_trans_xls_token='delete_xls' #标识符号,为了后面删除新建xls文件self.delete_xlsx_trans_xls_list.append(self.filename_xls) #如果生成多个xls文件,就把他放入list,方便后期删除文件#这里打开excel文件主要是为了获取sheet,为了下拉框数据data=self.OpenExcelFile(self.file_path)#获取sheet名称sheetName= data.sheet_names()#获取excel所有的sheet#print(sheetName)self.sheet_value['value'] = sheetName#下拉框内容self.sheet_value.current(0)#默认设置显示第一个elif str(os.path.splitext(filename)[-1])=='.xls':#文件为xls文件,就不需要转换#get_value.set(filename)#print('文件名为%s'%filename)self.filename_dir=os.path.dirname(filename)#获取文件目录路径#print('文件为%s'%self.filename_dir)self.get_value.set(filename) #entry标签设置内容self.file_path = self.get_value.get() #获取文件路径内容,后面打开文件的路径是用这个路径self.delete_xlsx_trans_xls_token='not_delete_xls' #标识符号#这里打开excel文件主要是为了获取sheet,为了下拉框数据data=self.OpenExcelFile(filename)#获取sheet名称sheetName= data.sheet_names()#获取excel所有的sheet#print(sheetName)self.sheet_value['value'] = sheetName#下拉框内容self.sheet_value.current(0)#默认设置显示第一个except Exception as e:self.clear_entry()#清空内容#清空listself.clear_tree_value(self.field_tree)#清除text内容self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('打开Excel文件','打开失败,报错信息为:'+str(e))

3.3  获取sheet、行列数

 def get_start_end_row_col_value(self):#print('开始行为%s,结束行为%s,开始列为%s,结束列为%s'%(self.start_row.get(),self.end_row.get(),self.start_col.get(),self.end_col.get()))#表名称位置self.start_row_value=self.start_row.get()success_start_row_value=re.match('^[1-9]{1}$|^[0-9]{2,}$',self.start_row_value)self.end_row_value=self.end_row.get()success_end_row_value=re.match('^[1-9]{1}$|^[0-9]{2,}$',self.end_row_value)self.start_col_value=self.start_col.get()success_start_col_value=re.match('^[a-zA-Z]{1}$|^[a-zA-Z]{1}\d+$',self.start_col_value)self.end_col_value=self.end_col.get()success_end_col_value=re.match('^[a-zA-Z]{1}$|^[a-zA-Z]{1}\d+$',self.end_col_value)#表名字段位置self.start_row_field_value=self.start_row_field.get()success_start_row_field_value=re.match('^[1-9]{1}$|^[0-9]{2,}$',self.start_row_field_value)self.end_row_field_value=self.end_row_field.get()success_end_row_field_value=re.match('^[1-9]{1}$|^[0-9]{2,}$',self.end_row_field_value)self.start_col_field_value=self.start_col_field.get()success_start_col_field_value=re.match('^[a-zA-Z]{1}$|^[a-zA-Z]{1}\d+$',self.start_col_field_value)self.end_col_field_value=self.end_col_field.get()success_end_col_field_value=re.match('^[a-zA-Z]{1}$|^[a-zA-Z]{1}\d+$',self.end_col_field_value)#print(self.file_path)#Excel的sheetself.sheet_value_number=self.sheet_value.get()#success_sheet_value_number=re.match('^[1-9]{1}$|^[0-9]{2,}$',self.sheet_value_number)if success_start_row_value!=None and success_end_row_value!=None and success_start_col_value!=None and success_end_col_value!=None and success_start_row_field_value!=None and success_end_row_field_value!=None and success_start_col_field_value!=None and success_end_col_field_value!=None:#输入的位置信息符合规范,才继续执行查找数据#根据行列数获取具体数据self.Get_Excel_value('success')else:#输入的位置信息符合不规范if success_start_row_value==None:#信息不规范,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('填写位置信息不规范','填写的表名开始行数不规范,应该填写数字(填写的数字要大于等于1)')elif success_end_row_value==None :#信息不规范,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('填写位置信息不规范','填写的表名结束行数不规范,应该填写数字(填写的数字要大于等于1)')elif success_start_col_value==None :#信息不规范,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('填写位置信息不规范','填写的表名开始列数不规范,应该填写字母(例如a、a1、A、A1)')elif success_end_col_value==None :#信息不规范,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('填写位置信息不规范','填写的表名结束列数不规范,应该填写字母(例如a、a1、A、A1)')elif success_start_row_field_value==None :#信息不规范,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('填写位置信息不规范','填写的表名、字段、注释开始行数不规范,应该填写数字(填写的数字要大于等于1)')elif success_end_row_field_value==None :#信息不规范,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('填写位置信息不规范','填写的表名、字段、注释开始行数不规范,应该填写数字(填写的数字要大于等于1)')elif success_start_col_field_value==None :#信息不规范,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('填写位置信息不规范','填写的表名、字段、注释开始列数不规范,应该填写字母(例如a、a1、A、A1)')elif success_end_col_field_value==None :self.display_messagebox_error_success('填写位置信息不规范','填写的表名、字段、注释结束列数不规范,应该填写字母(例如a、a1、A、A1)')

3.4  获取表名称

def GetExcel_TableName(self,data,sheet_name,TableName_row_start,TableName_row_end,TableName_column_start,TableName_column_end):try:# 根据sheet_name下标选择读取内容sheetvalue = data.sheet_by_name(sheet_name)#将输入的列名号转换成数字列号column_start_number=Col2Int(TableName_column_start.upper())column_end_number=Col2Int(TableName_column_end.upper())if int(TableName_row_start)<=int(TableName_row_end):#开始行小于等于结束行if column_start_number<=column_end_number:#开始列小于等于结束列#取表名TableName_dict={}#用于存放表名及注释TableName=sheetvalue.row_values(int(TableName_row_start)-1,int(column_start_number)-1,int(column_end_number))[0]TableName_dict[TableName]=sheet_name#print(TableName_dict)return TableName_dictelse:return '表名开始列和结束列顺序填写错误,开始列应该在结束列前面。'else:return '表名开始行和结束行顺序填写错误,开始行应该小于等于结束行。'except Exception as e: return '查找表名称失败,原因:'+str(e)+' ,请查看开始行、结束行、开始列、结束列是否填写正确!!'

3.5 获取字段、类型、注释

def GetExcel_TableField(self,data,sheet_name,TableField_row_start,TableField_row_end,TableField_column_start,TableField_column_end):try:# 根据sheet_name下标选择读取内容sheetvalue = data.sheet_by_name(sheet_name)#将输入的列名号转换成数字列号column_start_number=Col2Int(TableField_column_start.upper())column_end_number=Col2Int(TableField_column_end.upper())if int(TableField_row_start)<=int(TableField_row_end):#开始行小于等于结束行if column_end_number-column_start_number+1==3 and column_end_number>=column_start_number:#获取表字段、类型、注释列数有3列#取表字段及注释TableField_dict={} #建立一个字典存放字段名称和注释TableField_dict1={} #建立一个字典存放字段名称和字段类型for i in range(int(TableField_row_start),int(TableField_row_end)+1):TableFieldName=sheetvalue.row_values(i-1,column_start_number-1,column_end_number)[0]TableFieldComment=sheetvalue.row_values(i-1,column_start_number-1,column_end_number)[1]TableFieldKind=sheetvalue.row_values(i-1,column_start_number-1,column_end_number)[2]if TableFieldName!='': #表名称为空的值,不放入字典中TableField_dict[TableFieldName]=TableFieldCommentTableField_dict1[TableFieldName]=TableFieldKind#print('表内容为%s' %(TableField_dict))#del TableField_dict['']#删除表名称为空的值#del TableField_dict1['']#删除表名称为空的值return TableField_dict,TableField_dict1else:#self.display_messagebox_error_success('填写sheet不规范','填写的sheet不规范,应该填写数字(填写的数字要大于等于1)')return '字段、类型、注释列数不对,应该要有3列。','字段、类型、注释列数不对,应该要有3列。'else:return '表字段、类型、注释开始行和结束行顺序填写错误,开始行应该小于等于结束行。','表字段、类型、注释开始行和结束行顺序填写错误,开始行应该小于等于结束行。'except Exception as e:print('错误信息:eeeee%s'%e)return '查找字段、类型、注释失败,原因:'+str(e)+' ,请查看开始行、结束行、开始列、结束列是否填写正确!!','查找表字段及注释失败,原因:'+str(e)+' ,请查看开始行、结束行、开始列、结束列是否填写正确!!'

3.6 根据sheet、列数获取具体数据

 #根据sheet、列数获取具体数据def Get_Excel_value(self,successinfo):    filename=self.file_path #获取路径必须在mainloop后面,这个file_path在class定义必须要加self#打开excel获取数据data=self.OpenExcelFile(filename)#获取表名self.TableName_dict=self.GetExcel_TableName(data,self.sheet_value_number,self.start_row_value,self.end_row_value,self.start_col_value,self.end_col_value)if isinstance(self.TableName_dict,dict): #获取名称成功#获取字段、类型、注释self.TableField_dict,self.TableField_dict1=self.GetExcel_TableField(data,self.sheet_value_number,self.start_row_field_value,self.end_row_field_value,self.start_col_field_value,self.end_col_field_value)if isinstance(self.TableField_dict,dict) and isinstance(self.TableField_dict1,dict):#获取字段、类型、注释成功#字段信息list显示self.show_field_list(self.TableField_dict,self.TableField_dict1)#for index, wifi_info in enumerate(TableField_dict):#print('index为%s,wifi_info为%s'%(index, wifi_info ))if self.mark_hive_pg_datebase=='hive':try:#print('这边走%s:'%self.mark_hive_pg_datebase)#创建表头、表尾写法self.tablename,self.string_CreateSql_1,self.string_CreateSql_3=self.CreateTableSql_1_3(self.TableName_dict,self.mark_hive_pg_datebase)#创建表中写法self.string_CreateSql_2,string_CreateSql_4=self.CreateTableSql_2(self.TableField_dict,self.TableField_dict1,'','',self.mark_hive_pg_datebase)#整个建表语句写法self.string_whole_CreateTableName=self.string_CreateSql_1+"\n"+self.string_CreateSql_2+"\n"+self.string_CreateSql_3#print(string_whole_CreateTableName)#如果编写sql语句成功,返回一个标识符。self.createSql_token='succrss_create_sql'except Exception as e:self.display_messagebox_error_success('查找表名、字段、注释','程序编辑sql语句失败')elif self.mark_hive_pg_datebase=='pg':try:#print('这边走%s:'%self.mark_hive_pg_datebase)#创建表头、表尾写法self.tablename,self.string_CreateSql_1,self.string_CreateSql_3=self.CreateTableSql_1_3(self.TableName_dict,self.mark_hive_pg_datebase)#创建表中写法self.string_CreateSql_2,string_CreateSql_4=self.CreateTableSql_2(self.TableField_dict,self.TableField_dict1,self.TableName_dict,self.tablename,self.mark_hive_pg_datebase)#整个建表语句写法self.string_whole_CreateTableName=self.string_CreateSql_1+"\n"+self.string_CreateSql_2+"\n"+self.string_CreateSql_3+"\n"+string_CreateSql_4#print(string_whole_CreateTableName)#如果编写sql语句成功,返回一个标识符。self.createSql_token='succrss_create_sql'except Exception as e:self.display_messagebox_error_success('查找表名、字段、注释','程序编辑sql语句失败')#将sql语句放入text预览,先清除text内容self.clear_text_value(self.view_sql_Text)self.view_sql_Text.insert('end', self.string_whole_CreateTableName)else:#获取字段、类型、注释失败#获取字段、类型、注释失败,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('查找表名、字段、注释',self.TableField_dict)else:#获取表名称失败#获取表名称失败,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('查找表名、字段、注释',self.TableName_dict)

3.7 保存建表文件 

#保存建表文件            保存文件目录路径def Save_sql_file(self,file_save_path):#sql语句写入文件中try:ack_success=''#print('self.createSql_token为%s'%self.createSql_token)if file_save_path!='' and self.createSql_token=='succrss_create_sql':#print('进去保存流程self.createSql_token为%s'%self.createSql_token)self.sql_filename=str(self.tablename)+'.sql'if os.path.isfile(self.sql_filename):#判断文件是否存在os.remove(self.sql_filename)#删除文件#print('文件存在,'+str(self.sql_filename)+'删除成功')with open(file_save_path+'/'+self.sql_filename,'w+',encoding='UTF-8') as file:file.write(self.string_whole_CreateTableName)file.close()ack_success='success'self.createSql_token='false_create_sql'return ack_successelse: #不存在#print('文件不存在,'+str(self.sql_filename)+',可以创建')with open(file_save_path+'/'+self.sql_filename,'w+',encoding='UTF-8') as file:file.write(self.string_whole_CreateTableName)file.close()ack_success='success'self.createSql_token='false_create_sql'return ack_successelse:self.display_messagebox_error_success('保存文件','请输入文件位置信息查询后,再点击保存!!')except Exception as e:return 'false'

3.8 弹窗模块

   #弹窗模块def display_messagebox_error_success(self,success_error_title,success_error_info):tk.messagebox.showinfo(title=str(success_error_title),message=str(success_error_info))

、 将代码打包成exe应用

我这里使用的是Anaconda3打包。

#创建虚拟环境 (有没有创建成功,可以在安装目录:D:\Anaconda3\envs())
conda create -n excel python=3.6

#激活虚拟环境 
conda activate excel

#Pyinstaller打包
Pyinstaller -F -w -i apple.ico Hive_CreateSQL.py

五、全部代码

# -*- coding: utf-8 -*-
"""
Created on Sun Oct  9 18:00:06 2022@author: Administrator
"""import xlrd
from openpyxl.utils import column_index_from_string as Col2Int
import tkinter as tk
from tkinter import ttk
from tkinter import *
import os
import re
import shutil
import random
import string
import win32com.client as win32import tkinter.filedialog  # 在Gui中打开文件浏览
import tkinter.messagebox  # 打开tkiner的消息提醒框from PIL import Image'''
row_values(row,col1,col2)  第row行,第col1列到col2列,不包括col2列
cell(row,col) 第row行,第col1列
col_values(col,row1,row2) 取第col列, 第row1行到row2行 不包括row2行# 获取到表的总行数
#nrows = sheet.nrows
#for i in range(nrows):#print(sheet.row_values(i))
'''class Excel_GUI():def __init__(self, init_window_name): #以下self结果是class返回的结果self.init_window_name = init_window_name#数据库选择self.get_select_datebase = tk.StringVar()  # 设置可变内容self.get_select_datebase.set('hive') #单选按钮默认选择hive按钮self.mark_hive_pg_datebase='hive' #默认设置成hive# Excel文件路径self.get_value = tk.StringVar()  # 设置可变内容#表名称self.get_start_row_value = tk.StringVar()  # 设置可变内容self.get_end_row_value = tk.StringVar()  # 设置可变内容self.get_start_col_value = tk.StringVar()  # 设置可变内容self.get_end_col_value = tk.StringVar()  # 设置可变内容#表字段self.get_start_row_field_value = tk.StringVar()  # 设置可变内容self.get_end_row_field_value = tk.StringVar()  # 设置可变内容self.get_start_col_field_value = tk.StringVar()  # 设置可变内容self.get_end_col_field_value = tk.StringVar()  # 设置可变内容#sheet数字self.get_sheet_value = tk.StringVar()  # 设置可变内容#self.filename={}#如果编写sql语句成功,返回一个标识符。self.createSql_token=''#输入文件是xlsx格式,给一个标识符self.delete_xlsx_trans_xls_token=''self.delete_xlsx_trans_xls_list=[]#打开excel文件def OpenExcelFile(self,filename):# 打开excel读取文件data = xlrd.open_workbook(filename)return data#取表名def GetExcel_TableName(self,data,sheet_name,TableName_row_start,TableName_row_end,TableName_column_start,TableName_column_end):try:# 根据sheet_name下标选择读取内容sheetvalue = data.sheet_by_name(sheet_name)#将输入的列名号转换成数字列号column_start_number=Col2Int(TableName_column_start.upper())column_end_number=Col2Int(TableName_column_end.upper())if int(TableName_row_start)<=int(TableName_row_end):#开始行小于等于结束行if column_start_number<=column_end_number:#开始列小于等于结束列#取表名TableName_dict={}#用于存放表名及注释TableName=sheetvalue.row_values(int(TableName_row_start)-1,int(column_start_number)-1,int(column_end_number))[0]TableName_dict[TableName]=sheet_name#print(TableName_dict)return TableName_dictelse:return '表名开始列和结束列顺序填写错误,开始列应该在结束列前面。'else:return '表名开始行和结束行顺序填写错误,开始行应该小于等于结束行。'except Exception as e: return '查找表名称失败,原因:'+str(e)+' ,请查看开始行、结束行、开始列、结束列是否填写正确!!'#获取字段、类型、注释def GetExcel_TableField(self,data,sheet_name,TableField_row_start,TableField_row_end,TableField_column_start,TableField_column_end):try:# 根据sheet_name下标选择读取内容sheetvalue = data.sheet_by_name(sheet_name)#将输入的列名号转换成数字列号column_start_number=Col2Int(TableField_column_start.upper())column_end_number=Col2Int(TableField_column_end.upper())if int(TableField_row_start)<=int(TableField_row_end):#开始行小于等于结束行if column_end_number-column_start_number+1==3 and column_end_number>=column_start_number:#获取表字段、类型、注释列数有3列#取表字段及注释TableField_dict={} #建立一个字典存放字段名称和注释TableField_dict1={} #建立一个字典存放字段名称和字段类型for i in range(int(TableField_row_start),int(TableField_row_end)+1):TableFieldName=sheetvalue.row_values(i-1,column_start_number-1,column_end_number)[0]TableFieldComment=sheetvalue.row_values(i-1,column_start_number-1,column_end_number)[1]TableFieldKind=sheetvalue.row_values(i-1,column_start_number-1,column_end_number)[2]if TableFieldName!='': #表名称为空的值,不放入字典中TableField_dict[TableFieldName]=TableFieldCommentTableField_dict1[TableFieldName]=TableFieldKind#print('表内容为%s' %(TableField_dict))#del TableField_dict['']#删除表名称为空的值#del TableField_dict1['']#删除表名称为空的值return TableField_dict,TableField_dict1else:#self.display_messagebox_error_success('填写sheet不规范','填写的sheet不规范,应该填写数字(填写的数字要大于等于1)')return '字段、类型、注释列数不对,应该要有3列。','字段、类型、注释列数不对,应该要有3列。'else:return '表字段、类型、注释开始行和结束行顺序填写错误,开始行应该小于等于结束行。','表字段、类型、注释开始行和结束行顺序填写错误,开始行应该小于等于结束行。'except Exception as e:print('错误信息:eeeee%s'%e)return '查找字段、类型、注释失败,原因:'+str(e)+' ,请查看开始行、结束行、开始列、结束列是否填写正确!!','查找表字段及注释失败,原因:'+str(e)+' ,请查看开始行、结束行、开始列、结束列是否填写正确!!'#创建表头、表尾写法           表名:表注释def CreateTableSql_1_3(self,dict_name,Select_database):#print('创建表头、表尾为:%s'%Select_database)if Select_database=='hive':#hive表头、表尾写法for key,value in dict_name.items():string_CreateSql_1='CREATE TABLE IF NOT EXISTS '+str(key)+'('string_CreateSql_3=")\nCOMMENT '"+str(value)+"'\nROW FORMAT DELIMITED FIELDS TERMINATED BY '\\u001' STORED AS ORCFILE;"#print(string_CreateSql_3return key,string_CreateSql_1,string_CreateSql_3elif Select_database=='pg':#pg表头、表尾写法for key,value in dict_name.items():string_CreateSql_1="CREATE TABLE "+str(key)+" ("string_CreateSql_3=");"#print(string_CreateSql_3return key,string_CreateSql_1,string_CreateSql_3#创建表中写法              字段:注释  字段:字段类型 表名:表注释  表名def CreateTableSql_2(self,dict_name,dict_name1,dict_tablename,tablename,Select_database):#print('创建表中为:%s'%Select_database)if Select_database=='hive':#hive表中写法string_CreateSql_2=""dict_length=1for key,value in dict_name.items():if dict_length==len(dict_name): #最后一个字段末尾不需要加逗号string_CreateSql_2=string_CreateSql_2+"\t"+str(key)+" "+str(dict_name1[key])+" COMMENT '"+str(value)+"'"else:string_CreateSql_2=string_CreateSql_2+"\t"+str(key)+" "+str(dict_name1[key])+" COMMENT '"+str(value)+"',\n"dict_length=dict_length+1return string_CreateSql_2,''elif Select_database=='pg':#pg表中写法string_CreateSql_2="" #表字段加字段类型部分 如batch_id varchar(500) string_CreateSql_4="" #表字段注释加表注释dict_length=1for key,value in dict_name1.items():if dict_length==len(dict_name1): #最后一个字段末尾不需要加逗号string_CreateSql_2=string_CreateSql_2+"\t"+str(key)+" "+str(dict_name1[key])else:string_CreateSql_2=string_CreateSql_2+"\t"+str(key)+" "+str(dict_name1[key])+",\n"dict_length=dict_length+1for key,value in dict_name.items():string_CreateSql_4=string_CreateSql_4+"COMMENT ON COLUMN "+str(tablename)+"."+str(key)+" IS '"+str(value)+"';\n"string_CreateSql_4=string_CreateSql_4+"\nCOMMENT ON TABLE "+str(tablename)+" IS '"+str(dict_tablename[tablename])+"';"return string_CreateSql_2,string_CreateSql_4#将xlsx文件转化为xls文件def xlsx_to_xls(self,fname, export_name, delete_flag=False):"""将xlsx文件转化为xls文件:param fname: 传入待转换的文件路径(可传绝对路径,也可传入相对路径,都可以):param export_name: 传入转换后到哪个目录下的路径(可传绝对路径,也可传入相对路径,都可以):param delete_flag: 转换成功后,是否删除原来的xlsx的文件,默认删除 布尔类型:return:    无返回值"""excel = win32.gencache.EnsureDispatch('Excel.Application')excel.Visible = Falseexcel.DisplayAlerts = Falseabsolute_path = os.path.join(os.path.dirname(os.path.abspath(fname)), os.path.basename(fname))save_path = os.path.join(os.path.dirname(os.path.abspath(export_name)), os.path.basename(export_name))wb = excel.Workbooks.Open(absolute_path)wb.SaveAs(save_path, FileFormat=56)  # FileFormat = 51 is for .xlsx extensionwb.Close()  # FileFormat = 56 is for .xls extensionexcel.Application.Quit()if delete_flag:os.remove(absolute_path)# 添加文件目录def add_Excel_file(self):      try:filename = tkinter.filedialog.askopenfilename(title=u'打开文件')self.clear_entry()#清空内容#清空listself.clear_tree_value(self.field_tree)#清除text内容self.clear_text_value(self.view_sql_Text)if filename!='': #如果关闭选择窗口会返回一个空值if str(os.path.splitext(filename)[-1])=='.xlsx': #如果选择的文件为xlsx文件,就需要转换成xls文件#get_value.set(filename)#print('文件名为%s'%filename)self.random_string=self.create_string_number(8)#随机生成6位字符串self.filename_dir=os.path.dirname(filename)#获取文件目录路径#print('文件为%s'%self.filename_dir)fname_path=filenameexport_name_path=self.filename_dir+str()#转换后的新xls文件名    self.filename_xls=str(os.path.splitext(filename)[0])+'_'+str(self.random_string)+'.xls'#转换函数self.xlsx_to_xls(fname=fname_path, export_name=self.filename_xls, delete_flag=False)self.get_value.set(filename) #entry标签设置内容self.file_path =self.filename_xls #获取文件路径内容,后面打开文件的路径是用这个路径self.delete_xlsx_trans_xls_token='delete_xls' #标识符号,为了后面删除新建xls文件self.delete_xlsx_trans_xls_list.append(self.filename_xls) #如果生成多个xls文件,就把他放入list,方便后期删除文件#这里打开excel文件主要是为了获取sheet,为了下拉框数据data=self.OpenExcelFile(self.file_path)#获取sheet名称sheetName= data.sheet_names()#获取excel所有的sheet#print(sheetName)self.sheet_value['value'] = sheetName#下拉框内容self.sheet_value.current(0)#默认设置显示第一个elif str(os.path.splitext(filename)[-1])=='.xls':#文件为xls文件,就不需要转换#get_value.set(filename)#print('文件名为%s'%filename)self.filename_dir=os.path.dirname(filename)#获取文件目录路径#print('文件为%s'%self.filename_dir)self.get_value.set(filename) #entry标签设置内容self.file_path = self.get_value.get() #获取文件路径内容,后面打开文件的路径是用这个路径self.delete_xlsx_trans_xls_token='not_delete_xls' #标识符号#这里打开excel文件主要是为了获取sheet,为了下拉框数据data=self.OpenExcelFile(filename)#获取sheet名称sheetName= data.sheet_names()#获取excel所有的sheet#print(sheetName)self.sheet_value['value'] = sheetName#下拉框内容self.sheet_value.current(0)#默认设置显示第一个except Exception as e:self.clear_entry()#清空内容#清空listself.clear_tree_value(self.field_tree)#清除text内容self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('打开Excel文件','打开失败,报错信息为:'+str(e))'''self.random_string=self.create_string_number(6)#随机生成6位字符串self.filename_dir=os.path.dirname(filename)if str(os.path.splitext(filename)[-1])=='.xlsx':self.filename_xls=str(os.path.splitext(filename)[0:-1][0])+'_'+str(self.random_string)+'.xls'#shutil.copyfile(filename,self.filename_dir)#根据xlsx文件创建xls文件self.a="copy "+str(filename)+' '+str(self.filename_xls)os.popen(self.a)print('1111111111')elif str(os.path.splitext(filename)[-1])=='.xls':print('22222222222')self.filename_xlsx=filename#os.remove(self.filename_xls)#删除文件self.get_value.set(filename) #entry标签设置内容self.file_path = self.get_value.get() #获取路径内容#这里打开excel文件主要是为了获取sheet,为了下拉框数据data=self.OpenExcelFile(self.filename_xls)#获取sheet名称sheetName= data.sheet_names()#获取excel所有的sheet#print(sheetName)self.sheet_value['value'] = sheetName#下拉框内容self.sheet_value.current(0)#默认设置显示第一个'''# self.init_window_name.destory()#获取sheet、行列数def get_start_end_row_col_value(self):#print('开始行为%s,结束行为%s,开始列为%s,结束列为%s'%(self.start_row.get(),self.end_row.get(),self.start_col.get(),self.end_col.get()))#表名称位置self.start_row_value=self.start_row.get()success_start_row_value=re.match('^[1-9]{1}$|^[0-9]{2,}$',self.start_row_value)self.end_row_value=self.end_row.get()success_end_row_value=re.match('^[1-9]{1}$|^[0-9]{2,}$',self.end_row_value)self.start_col_value=self.start_col.get()success_start_col_value=re.match('^[a-zA-Z]{1}$|^[a-zA-Z]{1}\d+$',self.start_col_value)self.end_col_value=self.end_col.get()success_end_col_value=re.match('^[a-zA-Z]{1}$|^[a-zA-Z]{1}\d+$',self.end_col_value)#表名字段位置self.start_row_field_value=self.start_row_field.get()success_start_row_field_value=re.match('^[1-9]{1}$|^[0-9]{2,}$',self.start_row_field_value)self.end_row_field_value=self.end_row_field.get()success_end_row_field_value=re.match('^[1-9]{1}$|^[0-9]{2,}$',self.end_row_field_value)self.start_col_field_value=self.start_col_field.get()success_start_col_field_value=re.match('^[a-zA-Z]{1}$|^[a-zA-Z]{1}\d+$',self.start_col_field_value)self.end_col_field_value=self.end_col_field.get()success_end_col_field_value=re.match('^[a-zA-Z]{1}$|^[a-zA-Z]{1}\d+$',self.end_col_field_value)#print(self.file_path)#Excel的sheetself.sheet_value_number=self.sheet_value.get()#success_sheet_value_number=re.match('^[1-9]{1}$|^[0-9]{2,}$',self.sheet_value_number)if success_start_row_value!=None and success_end_row_value!=None and success_start_col_value!=None and success_end_col_value!=None and success_start_row_field_value!=None and success_end_row_field_value!=None and success_start_col_field_value!=None and success_end_col_field_value!=None:#输入的位置信息符合规范,才继续执行查找数据#根据行列数获取具体数据self.Get_Excel_value('success')else:#输入的位置信息符合不规范if success_start_row_value==None:#信息不规范,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('填写位置信息不规范','填写的表名开始行数不规范,应该填写数字(填写的数字要大于等于1)')elif success_end_row_value==None :#信息不规范,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('填写位置信息不规范','填写的表名结束行数不规范,应该填写数字(填写的数字要大于等于1)')elif success_start_col_value==None :#信息不规范,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('填写位置信息不规范','填写的表名开始列数不规范,应该填写字母(例如a、a1、A、A1)')elif success_end_col_value==None :#信息不规范,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('填写位置信息不规范','填写的表名结束列数不规范,应该填写字母(例如a、a1、A、A1)')elif success_start_row_field_value==None :#信息不规范,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('填写位置信息不规范','填写的表名、字段、注释开始行数不规范,应该填写数字(填写的数字要大于等于1)')elif success_end_row_field_value==None :#信息不规范,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('填写位置信息不规范','填写的表名、字段、注释开始行数不规范,应该填写数字(填写的数字要大于等于1)')elif success_start_col_field_value==None :#信息不规范,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('填写位置信息不规范','填写的表名、字段、注释开始列数不规范,应该填写字母(例如a、a1、A、A1)')elif success_end_col_field_value==None :self.display_messagebox_error_success('填写位置信息不规范','填写的表名、字段、注释结束列数不规范,应该填写字母(例如a、a1、A、A1)')#清空list   def clear_tree_value(self,treelist):tree_value=treelist.get_children()#返回结果是元组#print(type(tree_value))for item in tree_value:  #或者用这种写法[your_treeview.delete(item) for item in items]treelist.delete(item)#清空text def clear_text_value(self,text):text.delete('0.0', END) #从第一行第一列开始删除#清空目录、填写的位置信息def clear_entry(self):self.Excel_path.delete(0, END)self.start_row.delete(0, END)self.end_row.delete(0, END)self.start_col.delete(0, END)self.end_col.delete(0, END)self.start_row_field.delete(0, END)self.end_row_field.delete(0, END)self.start_col_field.delete(0, END)self.end_col_field.delete(0, END)self.sheet_value.delete(0, END)# 显示字段列表def show_field_list(self, TableField_dict,TableField_dict1):#插入list前,先清空列表self.clear_tree_value(self.field_tree)#tree_value=self.field_tree.get_children()#返回结果是元组#for item in tree_value:  #或者用这种写法[your_treeview.delete(item) for item in items]#   self.field_tree.delete(item)#往列表中插入值for index, field in enumerate(TableField_dict):self.field_tree.insert("", 'end', values=(index + 1,field,TableField_dict1[field],TableField_dict[field]))#再次判断list是否有数据,如果有数据说明查找成功,没有就是失败。if self.field_tree.get_children():#不为空#tk.messagebox.showinfo(title='查找字段和注释',message='查找成功,请核对表信息')  # 消息提醒弹窗,点击确定返回值为 okself.display_messagebox_error_success('查找字段和注释','查找成功,请核对表信息')#根据sheet、列数获取具体数据def Get_Excel_value(self,successinfo):    filename=self.file_path #获取路径必须在mainloop后面,这个file_path在class定义必须要加self#打开excel获取数据data=self.OpenExcelFile(filename)#获取表名self.TableName_dict=self.GetExcel_TableName(data,self.sheet_value_number,self.start_row_value,self.end_row_value,self.start_col_value,self.end_col_value)if isinstance(self.TableName_dict,dict): #获取名称成功#获取字段、类型、注释self.TableField_dict,self.TableField_dict1=self.GetExcel_TableField(data,self.sheet_value_number,self.start_row_field_value,self.end_row_field_value,self.start_col_field_value,self.end_col_field_value)if isinstance(self.TableField_dict,dict) and isinstance(self.TableField_dict1,dict):#获取字段、类型、注释成功#字段信息list显示self.show_field_list(self.TableField_dict,self.TableField_dict1)#for index, wifi_info in enumerate(TableField_dict):#print('index为%s,wifi_info为%s'%(index, wifi_info ))if self.mark_hive_pg_datebase=='hive':try:#print('这边走%s:'%self.mark_hive_pg_datebase)#创建表头、表尾写法self.tablename,self.string_CreateSql_1,self.string_CreateSql_3=self.CreateTableSql_1_3(self.TableName_dict,self.mark_hive_pg_datebase)#创建表中写法self.string_CreateSql_2,string_CreateSql_4=self.CreateTableSql_2(self.TableField_dict,self.TableField_dict1,'','',self.mark_hive_pg_datebase)#整个建表语句写法self.string_whole_CreateTableName=self.string_CreateSql_1+"\n"+self.string_CreateSql_2+"\n"+self.string_CreateSql_3#print(string_whole_CreateTableName)#如果编写sql语句成功,返回一个标识符。self.createSql_token='succrss_create_sql'except Exception as e:self.display_messagebox_error_success('查找表名、字段、注释','程序编辑sql语句失败')elif self.mark_hive_pg_datebase=='pg':try:#print('这边走%s:'%self.mark_hive_pg_datebase)#创建表头、表尾写法self.tablename,self.string_CreateSql_1,self.string_CreateSql_3=self.CreateTableSql_1_3(self.TableName_dict,self.mark_hive_pg_datebase)#创建表中写法self.string_CreateSql_2,string_CreateSql_4=self.CreateTableSql_2(self.TableField_dict,self.TableField_dict1,self.TableName_dict,self.tablename,self.mark_hive_pg_datebase)#整个建表语句写法self.string_whole_CreateTableName=self.string_CreateSql_1+"\n"+self.string_CreateSql_2+"\n"+self.string_CreateSql_3+"\n"+string_CreateSql_4#print(string_whole_CreateTableName)#如果编写sql语句成功,返回一个标识符。self.createSql_token='succrss_create_sql'except Exception as e:self.display_messagebox_error_success('查找表名、字段、注释','程序编辑sql语句失败')#将sql语句放入text预览,先清除text内容self.clear_text_value(self.view_sql_Text)self.view_sql_Text.insert('end', self.string_whole_CreateTableName)else:#获取字段、类型、注释失败#获取字段、类型、注释失败,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('查找表名、字段、注释',self.TableField_dict)else:#获取表名称失败#获取表名称失败,弹窗之前,先把text、treelist信息删除self.clear_tree_value(self.field_tree)self.clear_text_value(self.view_sql_Text)self.display_messagebox_error_success('查找表名、字段、注释',self.TableName_dict)#保存建表文件            保存文件目录路径def Save_sql_file(self,file_save_path):#sql语句写入文件中try:ack_success=''#print('self.createSql_token为%s'%self.createSql_token)if file_save_path!='' and self.createSql_token=='succrss_create_sql':#print('进去保存流程self.createSql_token为%s'%self.createSql_token)self.sql_filename=str(self.tablename)+'.sql'if os.path.isfile(self.sql_filename):#判断文件是否存在os.remove(self.sql_filename)#删除文件#print('文件存在,'+str(self.sql_filename)+'删除成功')with open(file_save_path+'/'+self.sql_filename,'w+',encoding='UTF-8') as file:file.write(self.string_whole_CreateTableName)file.close()ack_success='success'self.createSql_token='false_create_sql'return ack_successelse: #不存在#print('文件不存在,'+str(self.sql_filename)+',可以创建')with open(file_save_path+'/'+self.sql_filename,'w+',encoding='UTF-8') as file:file.write(self.string_whole_CreateTableName)file.close()ack_success='success'self.createSql_token='false_create_sql'return ack_successelse:self.display_messagebox_error_success('保存文件','请输入文件位置信息查询后,再点击保存!!')except Exception as e:return 'false'#弹窗模块def display_messagebox_error_success(self,success_error_title,success_error_info):tk.messagebox.showinfo(title=str(success_error_title),message=str(success_error_info))#保存文件成功弹窗def display_messagebox(self): #自定义保存目录file_save_path = tkinter.filedialog.askdirectory(title=u'保存文件')#print(file_save_path)ack_success=self.Save_sql_file(file_save_path)if ack_success=='success':tk.messagebox.showinfo(title='保存文件',message='保存建表文件成功')  # 消息提醒弹窗,点击确定返回值为 ok#清空目录和位置信息self.clear_entry()#清空listself.clear_tree_value(self.field_tree)#清除text内容self.clear_text_value(self.view_sql_Text)#保存sql文件之后,删除新建的xls文件(针对原文件是xlsx文件)token=self.delete_xlsx_trans_xls_token#print('保存文件成功之后,token为%s'%token)if token=='delete_xls':delete_filename=self.filename_xlsif os.path.isfile(delete_filename):#判断文件是否存在#print('保存文件成功之后,删除文件为:%s'%delete_filename)os.remove(delete_filename)elif ack_success=='false':tk.messagebox.showinfo(title='保存文件',message='保存文件失败')  # 消息提醒弹窗,点击确定返回值为 ok#清空目录和位置信息self.clear_entry()#清空listself.clear_tree_value(self.field_tree)#清除text内容self.clear_text_value(self.view_sql_Text)#保存sql文件之后,删除新建的xls文件(针对原文件是xlsx文件)token=self.delete_xlsx_trans_xls_token#print('保存文件失败之后,token为%s'%token)if token=='delete_xls':delete_filename=self.filename_xlsif os.path.isfile(delete_filename):#判断文件是否存在#print('保存文件失败之后,删除文件为:delete_filename%s'%delete_filename)os.remove(delete_filename)#打开图片模块def Open_image(self):try:img=Image.open(r'./createtable_notice.png')img.show()except Exception as e: self.display_messagebox_error_success('提示!!',e)def create_string_number(self,n):"""生成一串指定位数的字符+数组混合的字符串"""m = random.randint(1, n)a = "".join([str(random.randint(0, 9)) for _ in range(m)])b = "".join([random.choice(string.ascii_letters) for _ in range(n - m)])return ''.join(random.sample(list(a + b), n))#点击hive数据库按钮def select_hive_database(self):self.mark_hive_pg_datebase=self.get_select_datebase.get()#清空目录和位置信息self.clear_entry()#清空listself.clear_tree_value(self.field_tree)#清空textself.clear_text_value(self.view_sql_Text)#print('点击数据库为:%s'%self.mark_hive_pg_datebase)#self.get_datebase.set('red')#点击pg数据库按钮   def select_pg_database(self):self.mark_hive_pg_datebase=self.get_select_datebase.get()#清空目录和位置信息self.clear_entry()#清空listself.clear_tree_value(self.field_tree)#清空textself.clear_text_value(self.view_sql_Text)#print('点击数据库为:%s'%self.mark_hive_pg_datebase)#self.get_datebase.set('red')#设置界面def SetGUI(self):self.init_window_name.title("Excel文件创建建表sql文件")self.init_window_name.geometry('1300x750')#self.init_window_name.overrideredirect(1) # 隐藏标题栏 最大化最小化按钮#self.init_window_name.attributes("-toolwindow", 2) # 去掉窗口最大化最小化按钮,只保留关闭self.init_window_name.resizable(0,0)# 禁止拉伸窗口##button_filename=add_Excel_file()#数据库选择部分self.select_database_labelframe = tk.LabelFrame(self.init_window_name,width=1280, height=53,text="数据库选择")self.select_database_labelframe.place(x=10,y=2)self.hive_Radiobutton = Radiobutton(self.select_database_labelframe,text="hive数据库",variable=self.get_select_datebase,value='hive',command=self.select_hive_database)self.hive_Radiobutton.place(x=50,y=0)self.pg_Radiobutton = Radiobutton(self.select_database_labelframe,text="pg数据库",variable=self.get_select_datebase,value='pg',command=self.select_pg_database)self.pg_Radiobutton.place(x=200,y=0)self.tip_label = tk.Label(self.select_database_labelframe,width=80,height=1,fg="red", bg="yellow", font=("微软雅黑", 12,"bold"), text="提示:选择的Excel文件最好是xls格式的。如果是xlsx格式的,按钮响应时间有点慢!!!")self.tip_label.place(x=420,y=0)#self.get_datebase_hive.set('hive')#self.pg_Radiobutton.select() #默认hive_Radiobutton这个按钮被选中#print(self.hive_Radiobutton.get())#excel文件模块#文件编辑部分labelframe = tk.LabelFrame(self.init_window_name,width=680, height=300, text="Excel文件")#labelframe.pack()labelframe.place(x=10,y=60)self.Excel_label = tk.Label(labelframe,width=10,height=1,fg='red', font=("微软雅黑", 10), text="目录路径:")self.Excel_label.place(x=0,y=2)self.Excel_path = tk.Entry(labelframe, width=60, textvariable=self.get_value)self.Excel_path.place(x=80,y=5)self.Excel_file = tk.Button(labelframe,width=23,height=1,fg='blue', text="选择Excel文件(只支持xls格式)",command=self.add_Excel_file)self.Excel_file.place(x=505,y=5)#表名self.start_row_label_location = tk.Label(labelframe,width=22,height=1,fg='red', font=("微软雅黑", 13),text="请填写表名位置信息", anchor="sw")self.start_row_label_location.place(x=0,y=38)self.start_row_label = tk.Label(labelframe,width=22,height=1, text="表名开始行(填写数字):")self.start_row_label.place(x=0,y=70)self.start_row = tk.Entry(labelframe, width=15, textvariable=self.get_start_row_value)self.start_row.place(x=160,y=70)self.end_row_label = tk.Label(labelframe,width=22,height=1, text="表名结束行(填写数字):")self.end_row_label.place(x=0,y=100)self.end_row = tk.Entry(labelframe, width=15, textvariable=self.get_end_row_value)self.end_row.place(x=160,y=100)self.start_col_label = tk.Label(labelframe,width=22,height=1, text="表名开始列(填写字母):")self.start_col_label.place(x=0,y=130)self.start_col = tk.Entry(labelframe, width=15, textvariable=self.get_start_col_value)self.start_col.place(x=160,y=130)self.end_col_label = tk.Label(labelframe,width=22,height=1, text="表名结束列(填写字母):")self.end_col_label.place(x=0,y=160)self.end_col = tk.Entry(labelframe, width=15, textvariable=self.get_end_col_value)self.end_col.place(x=160,y=160)#表字段self.start_row_label_field_location = tk.Label(labelframe,width=28,height=1,fg='red', font=("微软雅黑", 13),text="请填写表字段、注释、类型位置信息", anchor="sw")self.start_row_label_field_location.place(x=320,y=38)self.start_row_label_field = tk.Label(labelframe,width=24,height=1, text="表字段开始行(填写数字):")self.start_row_label_field.place(x=320,y=70)self.start_row_field = tk.Entry(labelframe, width=15, textvariable=self.get_start_row_field_value)self.start_row_field.place(x=494,y=70)self.end_row_label_field = tk.Label(labelframe,width=24,height=1, text="表字段结束行(填写数字):")self.end_row_label_field.place(x=320,y=100)self.end_row_field = tk.Entry(labelframe, width=15, textvariable=self.get_end_row_field_value)self.end_row_field.place(x=494,y=100)self.start_col_label_field = tk.Label(labelframe,width=24,height=1, text="表字段开始列(填写字母):")self.start_col_label_field.place(x=320,y=130)self.start_col_field = tk.Entry(labelframe, width=15, textvariable=self.get_start_col_field_value)self.start_col_field.place(x=494,y=130)self.end_col_label_field = tk.Label(labelframe,width=24,height=1, text="表字段结束列(填写字母):")self.end_col_label_field.place(x=320,y=160)self.end_col_field = tk.Entry(labelframe, width=15, textvariable=self.get_end_col_field_value)self.end_col_field.place(x=494,y=160)#输入sheet数字 页面改成下拉选择框self.sheet_label= tk.Label(labelframe,width=24,height=2,fg='green', text="请选择Excel中sheet", font=("微软雅黑", 14), anchor="sw")self.sheet_label.place(x=10,y=183)#self.sheet_value = tk.Entry(labelframe, width=15, textvariable=self.get_sheet_value)#self.sheet_value.place(x=10,y=245)self.sheet_value=ttk.Combobox(labelframe,textvariable=self.get_sheet_value)self.sheet_value.place(x=15,y=240)#self.sheet_value['value'] = ('下拉选项1', '下拉选项2', '下拉选项3', '下拉选项4')#self.sheet_value.current(0)#填写位置信息例子按钮self.Excel_field = tk.Button(labelframe,width=40,height=3,fg='blue', text="填写前,一定要点击我,查看位置信息格式!!!",command=self.Open_image)self.Excel_field.place(x=240,y=200)#查找按钮self.Excel_field = tk.Button(labelframe,width=17,height=3,fg='blue', text="查找表名、字段、注释",command=self.get_start_end_row_col_value)self.Excel_field.place(x=540,y=200)#保存文件按钮self.save_sql = tk.Button(labelframe,width=5,height=7,fg='blue', text="保存建表文件",wraplength=2,command=self.display_messagebox)self.save_sql.place(x=615,y=61)#list模块#字段显示列表LabelFrameself.field_labelframe = tk.LabelFrame(self.init_window_name,width=680, height=375,text="字段列表")self.field_labelframe.place(x=10,y=370)# 定义树形结构与滚动条self.field_tree = ttk.Treeview(self.field_labelframe, show="headings", columns=("a", "b", "c", "d"), height=16)self.vbar = Scrollbar(self.field_labelframe, orient='vertical', command=self.field_tree.yview,activerelief='ridge')#self.vbar.pack(side = tk.RIGHT, fill = tk.Y)self.field_tree.configure(yscrollcommand=self.vbar.set)# 表格的标题self.field_tree.column("a", width=100, anchor="center")self.field_tree.column("b", width=250, anchor="center")self.field_tree.column("c", width=150, anchor="center")self.field_tree.column("d", width=150, anchor="center")self.field_tree.heading("a", text="序号")self.field_tree.heading("b", text="字段名")self.field_tree.heading("c", text="字段类型",)self.field_tree.heading("d", text="注释")self.field_tree.place(x=0,y=3)# self.field_tree.bind("<Double-1>", self.onDBClick)self.vbar.place(x=653,y=3,relheight=0.99) #滚动条长度,取值在0-1之间#建表sql预览模块self.view_sql_labelframe = tk.LabelFrame(self.init_window_name,width=590, height=685,text="建表SQL预览")self.view_sql_labelframe.place(x=700,y=60)self.view_sql_Text = tk.Text(self.view_sql_labelframe,height=50, width=80,fg='red')self.view_sql_Text.place(x=0,y=5)self.view_sql_vbar = Scrollbar(self.view_sql_labelframe, orient='vertical', command=self.view_sql_Text.yview,activerelief='ridge')self.view_sql_Text.configure(yscrollcommand=self.view_sql_vbar.set)self.view_sql_vbar.place(x=565,y=5,relheight=0.99) #滚动条长度,取值在0-1之间if __name__=='__main__':init_window = tk.Tk() #获取tk对象ui=Excel_GUI(init_window) #tk对象传入Excel_GUI类中__init__方法,返回一个对象Excel_GUI.SetGUI(ui)init_window.mainloop()token=ui.delete_xlsx_trans_xls_token#print('token为%s'%token)if token=='delete_xls':#delete_filename=ui.filename_xlsdelete_filename=ui.delete_xlsx_trans_xls_listfor i in delete_filename:#print('删除文件为:delete_filename%s'%delete_filename)if os.path.isfile(i):#判断文件是否存在os.remove(i)

六、打包好的应用

在我csdn下载资源处

利用python编写exe应用,实现excel文件输出建表sql文件。相关推荐

  1. 车牌号对应的城市建表SQL文件

    SQL文件,下载后导入数据库就行,导入后表名为qm_usedcar_city.sql 点击这里下载

  2. Python Django通过牵引文件查看建表sql语句的命令sqlmigrate

  3. PDM和建表sql,PDM和EXCEL互转操作。

    一.PDM与建表sql互转 1.PDM转建表sql 选中表格,可以多选操作,然后按快捷键ctrl+g,复制Preview内容即可,最后会在桌面生成一个文件,用记事本打开即可. 2.建表sql转PDM ...

  4. 自动生成小工具(二):根据建表sql自动生成增删改查sql语句文件

    Mybatis自动生成插件虽然功能强大,但是也略显笨重.我自己开发了一个自动生成的小工具,更加简单,更加轻量级. 一共只有几百行代码,想改的话,直接修改即可.根据自己的实际情况,可以进行灵活的二次开发 ...

  5. pythonmat文件转excel_利用python将图片转换成excel文档格式详解

    本文主要介绍了关于利用python将图片转换成excel文档的相关内容,编写了一小段Python代码,将图片转为了Excel,纯属娱乐,下面这篇文章主要给大家介绍了关于利用python将图片转换成ex ...

  6. pythonmat文件转excel,利用python将图片转换成excel文档格式

    前言 本文主要介绍了关于利用python将图片转换成excel文档的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 实现步骤 读取图像,获取图像每个像素点的RGB值: 根据 ...

  7. python读取图片文字为表格_利用python将图片转换成excel文档格式

    前言 本文主要介绍了关于利用python将图片转换成excel文档的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 实现步骤 读取图像,获取图像每个像素点的RGB值: 根据 ...

  8. python将excel转换成图片格式_利用python将图片转换成excel文档格式

    前言 本文主要介绍了关于利用python将图片转换成excel文档的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 实现步骤 读取图像,获取图像每个像素点的RGB值: 根据 ...

  9. python日常实用技能:利用python将图片转换成excel文档格式

    @本文来源于公众号:csdn2299,喜欢可以关注公众号 程序员学府 前言 本文主要介绍了关于利用python将图片转换成excel文档的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详 ...

最新文章

  1. Linux_RHEL7_YUM
  2. 不停刷朋友圈的人_除夕夜!钦州人朋友圈刷爆了年夜饭,简直太丰盛了…
  3. 安装php报错误2356,linux下Mysql+php5+apache安装手记
  4. 【NOIP 2017】列队
  5. 常用时间序列分析方法
  6. wireshark 过滤法则
  7. Unity3D调用android方法(非插件方式)
  8. 如何去除快捷方式上的小箭头
  9. ARM寄存器的操作方法
  10. 软件测试思维总结(1)-----比较思维:利用好可参照的资源
  11. 百度拼音输入法 v2.10.2.52 官方免费版
  12. 【矩阵论】线性空间与线性变换(3)(4)
  13. 桥本分数式(蓝桥杯)
  14. 第4章 序言的具体写法
  15. 在Ubuntu18.04.3系统中安装谷歌拼音输入法(Google Pinyin)
  16. 如何安装markman
  17. ALLEGRO 中导入PADS的asc文件时显示pads_in.log does not exit
  18. 【RC延迟电路 RC充电电路】 multisim 14.0仿真 参数计算
  19. iOS开发 支付之银联支付集成
  20. IDEA创建Maven工程Servlet

热门文章

  1. 支小蜜智慧食堂刷脸支付系统,全面提升食堂管理水平
  2. C语言 解译电文密码
  3. 利用nginx搭建搭建直播平台中视频点播、直播、HLS服务器
  4. 超炫酷PS笔刷合集,拥有它你就是最闪的设计师
  5. IDEA提交代码进git+怎么导入sql文件进入数据库
  6. 使用Monkey进行软件测试(随机测试+脚本测试)
  7. ernie发音_Ernie[娥妮,厄尼]的中文翻译及英文名意思
  8. 计算机中的数制转换ppt,计算机基础知识数制转换课件.ppt
  9. 基金量化中交地产还能继续投吗?
  10. win10-Ubuntu双系统启动项设置