美文网首页
自动化办公系列2---xls/xlsx表格操作:多个表(个人信息

自动化办公系列2---xls/xlsx表格操作:多个表(个人信息

作者: SeekLife0 | 来源:发表于2021-09-07 15:44 被阅读0次

    项目下载github
    前言:这个操作Excel表格相关内容找了很久,很多代码都达不到想要的效果,但最后还是功夫不负有心人啊。

    一、开始之前的准备工作

    和自动化办公系列1这篇一样:自动化办公系列1

    二、开始多表(个人信息表)导入单表内容(汇总信息表)中

    需求:由于经常需要对一些现有的表如个人信息表进行汇总,全部汇总到一张表内,正常情况情况下就是一顿粘贴复制咯,有点累吧!那就让程序来完成。

    1、创建py文件的时候注意,2.7.15版本默认编码格式不是utf-8,而我们一般操作字符都是以utf-8的方式,故需要添加一些代码把编码格式转为utf-8。python3之后默认格式都是utf-8了。

    在文件开头添加如下代码:

    #coding=utf-8
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
    

    2、操作xlsx文件需要导入的模块

    2.1、 xlrd (读取xls的文件内容)
    2.2、 openpyxl(把内容写入到xlsx文件中)
    2.3、 pywin32 (方便调用windowsAPI)

    3、开始编写脚本

    #coding=utf-8
    import sys
    import xlrd
    import os
    import openpyxl
    import time
    import pythoncom
    import win32com.client as win32
    
    reload(sys)
    sys.setdefaultencoding('utf-8')
    
    
    # 读取路径下的所有文件名
    def read_file_name(file_dir):
        L = []
        for root,dirs,files in os.walk(file_dir):
            for file in files:
                L.append(file)
        return L
    
    # 进行xls到xlsx的转换
    def xlstoxlsx(filePath):
        if filePath.find('xls'):
            pythoncom.CoInitialize()
            excel = win32.gencache.EnsureDispatch('Excel.Application')
            filePath1 = filePath.decode('utf-8').encode('gbk')
            wb = None
            try:
                wb = excel.Workbooks.Open(filePath1)
                wb.SaveAs(filePath1 + 'x', FileFormat=51)  # FileFormat = 51 is for .xlsx extension
                print "xls转为xlsx的绝对路径为"+filePath + 'x'
            except IOError:
                print '文件读写错误'
            finally:
                wb.Close()
                excel.Application.Quit()
            time.sleep(2)  # 避免未及时关闭的情况,等待关闭完成
            return filePath1 + 'x'
    
    # 进行xlsx到xls的转换
    def xlsxtoxls(file,filePath):
        if file.find('xlsx'):
            pythoncom.CoInitialize()
            excel = win32.gencache.EnsureDispatch('Excel.Application')
            file = file.decode('utf-8').encode('gbk')
            # 去除末尾的x[-1:]
            # filepaths = filePath.split('.')
            # filePath1 = filepaths[0]
            filePath1 = "{}".format(filePath[:-4])
            filePath1 = filePath1.decode('utf-8').encode('gbk')
            # 打开文件需要进行异常捕获和关闭文件
            wb = None
            try:
                wb = excel.Workbooks.Open(file)
                wb.SaveAs(filePath1 + '.xls', FileFormat=56)  # FileFormat = 51 is for .xlsx extension
                print filePath1 + '.xls'
            except IOError:
                print '该文件读写发生错误'
            finally:
                wb.Close()
                excel.Application.Quit()
            time.sleep(1)  # 避免未及时关闭的情况,等待关闭完成
            return filePath1 + '.xls'
    
    # 写入到execel表格
    # 先打开原表然后复制一份最后另存为
    # values为单表内容总和 startCol为开始的列数 row为开始的行数 col为爬取的内容数
    def wExecel(path,row,col,startCol,values):
        # 这里最开始先判断一下填的路径是否存在
        print "是否存在路径判断"+path
        if os.path.isfile(path.decode('utf-8').encode('gbk')):
            # 这里需要对路径文件格式进行判断一个if语句
            if path.find('xlsx') != -1:                    # 把xlsx转为xls,会把原路径的xlsx文件替换
                xlsxPath = path.decode('utf-8').encode('gbk')
                print xlsxPath.decode('gbk').encode('utf-8')   #为了方便控制台查看转为utf-8
            else:
                print '文件格式为:xls'
                xlsxPath = xlstoxlsx(path)
                # 转换完成之后需要把原来xls这个文件删除
                path = path.decode('utf-8').encode('gbk')
                # os.remove(path)
                # print '原xls文件已删除'
            # wb = None
            try:
                wb = openpyxl.load_workbook(xlsxPath) # 打开这个xlsx文件得到wb对象
                sheetnames = wb.get_sheet_names()     # 获取文件内的所有表格
                # sheet = wb.get_sheet_by_name(sheetnames[0])
                for sheetname in sheetnames:          # 遍历这个文件的内的所有表格 这里只取第一个表
                    sheet = wb.get_sheet_by_name(sheetname)       # 取sheet表
                    # print "遍历的表格数" + str(j)
                    # range(start,stop,step) 开始 结束(不包括) 步长
                    for num in range(0, len(values)-(col-1), col):   # col每次遍历跳过的数 以col的数量为单位 len(values)一定是col的整数倍
                        for a in range(0, col):                      # 对一行数据进行操作 一共col列循环col次
                            value = str(values[num+a])               # 获取内容
                            # value = value.decode('utf-8').encode('gbk')
                            print "写入的内容" + value
                            sheet.cell(row, startCol+a).value = value  # 把内容写入到汇总表对应位置
                        row += 1
                    break
                    # j += 1
                # 这里保存的路径需要修改,只需要路径名
                print "最终保存路径---->"+xlsxPath.decode('gbk').encode('utf-8')       #为了方便控制台查看转为utf-8
                wb.save(xlsxPath)
            except IOError:
                print 'IO读写错误----->107'
        else:
            print "你填入的导出路径不存在请重新填写"
    
    # 该函数抓取导入的多张表的某些指定内容,内容指定由坐标表示
    # 因为涉及到一个文件可能存在多个表的问题所以要以表为单位进行内容抓取
    def rwExecel(Rpath,eList_col,eList_entry):
        # global list_col
        xlsPath = Rpath
        xls = None
        # 这里需要对路径文件格式进行判断一个if语句
        if 'xlsx' in Rpath:                    # 把xlsx转为xls,会把原路径的xlsx文件替换为xls,读的时候只能操作xls表格
            print '文件格式为:xlsx'
            xlsPath = xlsxtoxls(Rpath,Rpath)
            # 转换完成之后需要把原来xlsx这个文件删除
            path = Rpath.decode('utf-8').encode('gbk')
            os.remove(path)
            print '文件已删除'
            print xlsPath.decode('gbk').encode('utf-8')       #为了方便控制台查看转为utf-8
            # xls = xlrd.open_workbook(xlsPath)
        else:
            # xlsPath = xlsPath.decode('utf-8').encode('gbk')
            print xlsPath.decode('gbk').encode('utf-8')       #为了方便控制台查看转为utf-8
        # --------对xlsx文件内的所有表格都进行判断是否有内容-----------
        xls = xlrd.open_workbook(xlsPath)
        tables = xls.sheets()         # 获取文件所有表格这样就不需要表的标号和名称了
        sheet_name = xls.sheet_names()
        print sheet_name
        for table in tables:         # 如何判断一个表是否有内容
            if table.nrows == 0:     # 查看表的有效函数是否为0
                continue             # 直接进入下一个循环
            # 通过遍历elist_entry来获得对应坐标,每三个为一个单位获取
            for num in range(0,len(eList_entry)-2,3):
                # 只读入有效坐标只有行或列或者全没有不读入直接跳入下一个循环
                if (eList_entry[num+1]!='' and eList_entry[num+2]!='') and (eList_entry[num+1]!=None and eList_entry[num+2]!=None):
                    r = int(eList_entry[num+1])   # 第二个是行
                    c = int(eList_entry[num+2])   # 第三个是列
                    eList_col.append(table.cell_value(r,c)) # 爬取表格内容
                    print '每次爬取内容' + str(table.cell_value(r,c))
                else:
                    continue
            # wExecel(Wpath,eRow,eCol,eList_col) #写入的文件路径
            # del eList_col[:]  #每次执行完一行清空列表
            # eRow = eRow + 1
        return eList_col  # 返回装载所有多表信息的列表
    
    # 爬取表格内容并复制到表格力功能A
    # 多个表格内容复制到另一个表,一个表的内容就是一行
    def deal_Excel_A(start_row_col,content_row_col,importPath,exportPath):
        print u"开始执行任务"
        print '用户输入行数'+start_row_col[0]
        row = int(start_row_col[0]) + 1                       # 获得用户输入的开始行数
        print '用户输入列数'+start_row_col[1]
        col = int(start_row_col[1]) + 1                   # 获得用户输入的开始列数
        list_col = []                                     # 用来保存一个人的表格内容
        list_entry = content_row_col                      # 获得用户输入的行和列
        allFilesNames = read_file_name(importPath)        # 获取每个xls的表名
        i = 0
        for fileName in allFilesNames:                    # 遍历每个表名
            print fileName.decode('gbk').encode('utf-8')                               # 打印获得的每个表名 #为了方便控制台查看转为utf-8
            list_col = rwExecel(importPath + '/' + fileName,
                                list_col, list_entry)     # 抓取一张表的内容然后暂存到list_col
            i += 1
        print '遍历的表格文件数目---->' + str(i)
        # 读内容到列表完毕后进行统一写入操作
        wExecel(exportPath, row, len(list_entry)/3, col, list_col) # 把list_col的内容全部写入新的xlsx文件内
    
    # -------需要提供的数据--------
    start_row_col = ["1","1"]          # 最终导入的单表->数组第0个为开始行 数组第1个为开始列
    content_row_col = ["姓名","0","1", "年龄","0","3", "出生日期","1","1"]        # 抓取的坐标以及内容名称(表明这个坐标抓取的东西方便查看)
    
    
    
    if __name__ == '__main__':
        deal_Excel_A(start_row_col,content_row_col,"I:/pythonProject/xls_operation/importPath",
                     "I:/pythonProject/xls_operation/exportPath/某机构汇总表.xls")
    

    4、使用方式

    1、新建两个文件夹


    文件夹

    2、在对应的文件夹放入对应的文件


    多个个人信息表
    个人信息表格式
    汇总表
    汇总表格式

    3、按照对应规则填入参数
    注意:excecl表格的坐标是从0开始的,如第一个格子的位置为0,0

    # -------需要提供的数据--------
    start_row_col = ["1","1"]          # 最终导入的单表->数组第0个为开始行 数组第1个为开始列
    content_row_col = ["姓名","0","1", "年龄","0","3", "出生日期","1","1"]        # 抓取的坐标以及内容名称(表明这个坐标抓取的东西方便查看)
    
    
    
    if __name__ == '__main__':
        deal_Excel_A(start_row_col,content_row_col,"I:/pythonProject/xls_operation/importPath",
                     "I:/pythonProject/xls_operation/exportPath/某机构汇总表.xls")
    

    4.开始执行程序


    控制台显示的内容

    可以看到多出了一个xlsx的文件


    导入成功
    查看内容后发现数据已经填入了,这里从左到右填入的顺序是由你填入参数的那个数组顺序决定的,后面的数字代表就是个人信息表内容每个格子的坐标
    content_row_col = ["姓名","0","1", "年龄","0","3", "出生日期","1","1"] 
    
    填入成功

    使用注意事项:
    1、如果只是单纯的使用,复制我的代码按照之前说的环境即win10,python2.7.15下是可以正常使用的。
    2、使用时请关闭Excel或者wps等软件。
    3、程序中只使用了xlsToxlsx()函数,还有一个xlsxToxls()没使用,所以该方法删除也不影响脚本运行。
    注:转载请注明出处
    本文如果对你有帮助的话希望能给我点个赞哦~

    相关文章

      网友评论

          本文标题:自动化办公系列2---xls/xlsx表格操作:多个表(个人信息

          本文链接:https://www.haomeiwen.com/subject/xrcpwltx.html