zoukankan      html  css  js  c++  java
  • Python: 读写Excel(openpyxl / win32com.client)

    项目周报汇报的时候要做数据汇总,总是要从不同的excel文件中去获取数据最后汇总到一个excel表里面,所以决定用python直接写个自动化脚本来自动执行。

    用python来读写excel,目前找了2个方法:win32com.client和openpyxl

    • win32com.client可以对excel进行各种操作,可以调用VBA的库,相当于是模拟用户对excel进行操作,在执行过程中,你可以看到excel被打开,然后数据被写入,最后excel文件被关闭等等过程。(文档也可以参看OFFICE自带的VBA EXCEL 帮助文件(VBAXL.CHM)。这里面讲述了EXCEL VBA的编程概念, 另外,《Python Programming on Win32》书中也有很详细的介绍。这本书中(第九章)给出了一个类来操作EXCEL 文件,可以很容易的加以扩展。)
    • openpyxl是处理excel2007/2010及以后的格式,也就是xlsx系列,如果要处理以前的2003的表格(xls),那么则要用另外的库(xlrd/xlwt等)。

    python虽然并不是特别在意大小写,但是使用win32com.client一定要注意大小写,很多函数如果不区分大小写,是无法调用的,比如打开excel表格的Open函数,’O’必须大写,还有wb.Save(),‘S’也必须大写,而我们使用openpyxl使用小写即可。

    openpyxl在保存时用save(),很多原有的格式图表是无法保留下来的,比如对excel进行修改,里边原有的透视表,用openpyxl的save()是无法保存的,但是使用win32com.client的wb.Save()却是可以保存这些图表的,这也是更加方便的地方。

    这里简单分享项目中用到这2个模版的写数据方式:

    • 首先已经把数据都存到字典中:

    dict_data = {'ThinkPad_Users': 448177, 'IdeaPad_Users': 109626, 'Desktop_Users': 50605, 'Install_ThinkPad': 903036, 'Install_IdeaPad': 197467, 'Install_Desktop': 91656, 'ThinkPad_Fail': 8495, 'IdeaPad_Fail': 1970, 'Desktop_Fail': 1592}

    • 然后需要做的是把字典中的数据写入到excel表格中:

    使用win32com方法来修改Excel

    import win32com.client
    
    #使用win32com方法来修改Excel
    def modify_excel_win32com(dict_data, filename, title):
        #用于修改Excel的配置
        xlApp = win32com.client.Dispatch('Excel.Application')
    
        #用xlApp打开用于修改和写入数据
        xlBook = xlApp.Workbooks.Open(filename, ReadOnly = False)
    
        sheet = xlBook.Worksheets('WeeklyData'
        col_size = sheet.UsedRange.columns.Count + 1
        #判断该title是否存在;如存在则覆盖数据;如不存在则新建数据
        print(sheet.UsedRange.Value[0])
        if title in sheet.UsedRange.Value[0]:
            # print(sheet.UsedRange.Value[0].index(title))
            col_size = sheet.UsedRange.Value[0].index(title) + 1
        else:
            try:
                col_size = sheet.UsedRange.Value[0].index(None) + 1
            except:
                pass
            finally:
                sheet.Cells(1, col_size).Value = title
                print(col_size)
    
        for key, value in dict_data.items():
            if key=='Install_A':
                sheet.Cells(2, col_size).Value = value
            elif key=='A_Users':
                sheet.Cells(3, col_size).Value = value
            elif key=='A_Fail':
                sheet.Cells(4, col_size).Value = value
                sheet.Cells(5, col_size).Value = '%.2f%%' % (value / sheet.Cells(2, col_size).Value * 100)
                # print(sheet.Cells(5, col_size).Value)
            elif key=='Install_B':
                sheet.Cells(6, col_size).Value = value
            elif key=='B_Users':
                sheet.Cells(7, col_size).Value = value
            elif key=='B_Fail':
                sheet.Cells(8, col_size).Value = value
                sheet.Cells(9, col_size).Value = '%.2f%%' % (value / sheet.Cells(6, col_size).Value * 100)
            elif key=='Install_C':
                sheet.Cells(10, col_size).Value = value
            elif key=='C_Users':
                sheet.Cells(11, col_size).Value = value
            elif key=='C_Fail':
                sheet.Cells(12, col_size).Value = value
                sheet.Cells(13, col_size).Value = '%.2f%%' % (value / sheet.Cells(10, col_size).Value * 100)
                sheet.Cells(14, col_size).Value = '%.2f%%' % ((sheet.Cells(4, col_size).Value + sheet.Cells(8, col_size).Value + value) 
                                                    / (sheet.Cells(2, col_size).Value + sheet.Cells(6, col_size).Value + sheet.Cells(10, col_size).Value) 
                                                    * 100)
    
        xlBook.Save()     #保存  
        xlApp.quit()   #关闭excel操作环境。

    使用openpyxl库来修改Excel

    from openpyxl import worksheet
    from openpyxl import workbook
    from openpyxl import load_workbook
    from openpyxl.utils import get_column_letter
    
    #使用openpyxl库来修改Excel
    def modify_excel_openpyxl(dict_data, filename, title):    
        wb = load_workbook(filename)  #打开一个工作簿    
        sheet = wb['WeeklyData']  #获取一张表
        
        col_size = sheet.max_column+1
        first_row = []
        for i in range(1, col_size):
            first_row.append(sheet.cell(row=1, column=i).value)
        print(first_row)
        #判断该title是否存在;如存在则覆盖数据;如不存在则新建数据
        if title in first_row:
            col_size = first_row.index(title) + 1
        else:
            try:
                col_size = first_row.index(None) + 1
            except:
                pass
            finally:
                sheet.cell(row=1, column=col_size, value=title)
    
        print(get_column_letter(col_size))
        col_letter = get_column_letter(col_size)
        sheet[col_letter+'2'] = 'testtest'
    
        for key, value in dict_data.items():
            if key=='Install_A':
                sheet[col_letter+'2'] = value
            elif key=='A_Users':
                sheet[col_letter+'3'] = value
            elif key=='A_Fail':
                sheet[col_letter+'4'] = value
                sheet[col_letter+'5'] = '='+col_letter+'4/'+col_letter+'2'
            elif key=='Install_B':
                sheet[col_letter+'6'] = value
            elif key=='B_Users':
                sheet[col_letter+'7'] = value
            elif key=='B_Fail':
                sheet[col_letter+'8'] = value
                sheet[col_letter+'9'] = '='+col_letter+'8/'+col_letter+'6'
            elif key=='Install_C':
                sheet[col_letter+'10'] = value
            elif key=='C_Users':
                sheet[col_letter+'11'] = value
            elif key=='C_Fail':
                sheet[col_letter+'12'] = value
                sheet[col_letter+'13'] = '='+col_letter+'12/'+col_letter+'10'
                sheet[col_letter+'14'] = '=('+col_letter+'4+'+col_letter+'8+'+col_letter+'12)/('+col_letter+'2+'+col_letter+'6+'+col_letter+'10)'
    
        wb.save(filename)
        wb.close()
  • 相关阅读:
    项目是使用 Microsoft.AspNetCore.App 版本 2.1.20 还原的, 但使用当前设置, 将改用版本
    vs发布排除 文件
    win10部分低功耗蓝牙找不到
    解决JLINK_v8灯不亮 jtag 提示无法识别USB设备
    C# BYTE[] 与16进制字符串互相转换
    【转】阿里云证书资源包申请免费SSL流程(图文教程) 【免费证书申请将切换到证书资源包下】
    使用ApkTool以及dex2jar对apk进行反编译-更新异常以及解决方案
    使用ApkTool
    安装纯净版xp,,优盘装系统提示INF file txtsetup.sif的解决方法
    应急灾害管理相关英文关键词梳理--仅作为笔记
  • 原文地址:https://www.cnblogs.com/danvy/p/10605633.html
Copyright © 2011-2022 走看看