Python初学_做个简单操作Excel的程序

  •  前言

  有朋友让帮忙做个导出Excel的程序,正好看了github上很火的一个项目Python - 100天从新手到大师的相关内容就做了个简单的程序。

  废话不多,直接开干。

  •  需求

  需求很简单,就是把一个Excel中的内容每行内容导出一个固定模版的Excel表格,源文件单元格对应填入模板相应单元格中。

  • 程序设计流程图

 

  

  • 用的python库

下面说下用到的python库

tkinter:提供程序界面操作

openpyxl:提供对Excel的操作

string:自定义文字模版

re:正则表达式

os:文件操作

  • 源代码
import tkinter
import tkinter.messagebox
import tkinter.filedialog
from openpyxl import load_workbook
from openpyxl import Workbook
import os
from string import Template
import re

#  define main function
def main():
    # 创建导出目录
    if not os.path.exists('生成'):
        os.mkdir('生成')
    source_path = ""

    def get_source_path():
        nonlocal source_path
        source_path = tkinter.filedialog.askopenfilename(title='选择文件', filetypes=[('表格', '.xlsx')])
        label.config(text='文件路径:' + source_path)

    # create main top window
    top = tkinter.Tk()
    # set window-size
    top.geometry('640x360')
    # set window-title
    top.title("excel模版转换")
    # create text-obj
    label = tkinter.Label(top, text="文件路径:", font='Arial-32', fg='red')
    label.pack(side='top')

    # create panel container for btn
    panel = tkinter.Frame(top)
    # create btn-obj set into certain panel
    btn1 = tkinter.Button(panel, text='打开数据源文件', command=get_source_path)
    btn1.pack(side='left')
    btn2 = tkinter.Button(panel, text='生成', command=lambda: read_cell_maps(source_path))
    btn2.pack(side='right')
    panel.pack(side='bottom')
    # start main loop
    tkinter.mainloop()


# read excel-map text
def read_cell_maps(source_path):
    # read source-xls
    if os.path.isfile(source_path):
        source_workbook = load_workbook(source_path)
    else:
        tkinter.messagebox.showinfo('温馨提示', '源文件不存在')
        return

    # read target-model-xls
    if os.path.isfile('./模版.xlsx'):
        model_workbook = load_workbook('./模版.xlsx')
    else:
        tkinter.messagebox.showinfo('温馨提示', '模版文件不存在')
        return

    # read maps data set map-relation
    fo= open('./maps.txt','r')
    rowmap = [x for x in fo.readlines()]
    fo.close()
    for sheet in source_workbook.worksheets:
        rowcount = sheet.max_row
        print(sheet.title+':'+ str(rowcount))
        for rownum in range(int(rowmap[0]),rowcount+1):
            for map in rowmap[1].split(','):
                # 模版语句
                tempstring=map.split('=')[1]
                # 正则匹配
                pattern=re.compile('\\{(.*?)}')
                res=pattern.findall(tempstring)
                temp = Template(tempstring)
                # 设定模版内容
                mapdic={x:sheet[x+str(rownum)].value for x in res}
                # 此处将模版单元格数据替换成数据源单元格数据
                model_workbook.active[map.split('=')[0]].value=temp.safe_substitute(mapdic)
            # 另存为

            tempstring = rowmap[2]
            pattern = re.compile('\\{(.*?)}')
            res = pattern.findall(tempstring)
            temp = Template(tempstring)
            mapdic = {x: sheet[x + str(rownum)].value for x in res}
            temp.safe_substitute(mapdic)
            print(rowmap[2])
            model_workbook.save('./生成/{}.xlsx'.format(temp.safe_substitute(mapdic)))
    tkinter.messagebox.showinfo('温馨提示', '转换完成!')
if __name__ == '__main__':
    main()
查看代码

源代码打包文件:打包文件

  • 思考

1.程序很简单,没有将excel的操作单独做个操作类

2.学会了使用string template,方便套用各种字符串模版

3.可以优化的点:可以使用多线程分别处理不同的sheet,甚至多线程去处理每个sheet中的数据,这将大大提高运行速度

ps:源文件中sheet的格式要保持一致,否则会导致导出文件的单元格内容错误。

猜你喜欢

转载自www.cnblogs.com/Amyn/p/12676118.html