相关文章推荐
礼貌的金鱼  ·  poi 导出Excel ...·  2 年前    · 
热心肠的山羊  ·  C# 与vb.net ...·  2 年前    · 
风流的绿豆  ·  SCENIC | ...·  3 年前    · 

excel已经成为必不可少的数据处理软件,几乎天天在用。python有很多支持操作excel的第三方库,xlwings是其中一个。

关于xlwings
xlwings开源免费,能够非常方便的读写Excel文件中的数据,并且能够进行单元格格式的修改。

xlwings还可以和matplotlib、numpy以及pandas无缝连接,支持读写numpy、pandas数据类型,将matplotlib可视化图表导入到excel中。

最重要的是xlwings可以调用Excel文件中VBA写好的程序,也可以让VBA调用用Python写的程序。

开源免费,一直在更新

xlwings同类工具

python操作Excel的模块,网上提到的模块大致有:xlwings、xlrd、xlwt、openpyxl,pandas等。

xlwings功能总结

一、用python读写Excel文件,实际上就是读写有格式的文本文件,操作excel文件和操作text、csv文件没有区别,Excel文件只是用来储存数据。

二、除了操作数据,还可以调整Excel文件的表格宽度、字体颜色等。

另外需要提到的是用COM调用Excel的API操作Excel文档也是可行的,相当麻烦基本和VBA没有区别

xlwings中文文档

https://www.kancloud.cn/gnefnuy/xlwings-docs/1127474

xlwings结构图

# 打开Excel程序,默认设置:程序可见,只打开不新建工作薄,屏幕更新关闭
app=xw.App(visible=True,add_book=False)
app.display_alerts=False
app.screen_updating=False
# 其他操作:
# 屏幕更新。就是说代码对于excel的操作你可以看见。关闭实时更新,可以加快脚本运行。默认是True。
# app.screen_updating = False  
# App进程pid
# app.pid       
# 返回一个打开的全部workbook的列表。Python打开的和手动打开的是不互通的
# app.books     
# 终止进程,强制退出。
# app.quit() #不保存的情况下,退出excel程序

(三)工作簿

注意工作簿应该首先被打开

1、新建Excel文档

# 创建新的book
# 方式一
wb = app.books.add()
# 方式二
wk = xw.Book()
很多教程在提到新建App时都说这两种方式是一样的,实际上是有区别的,
方式1是在当前App下新建一个Book,
方式2是创建一个新的App,并在新App中新建一个Book
# 方式三,与方式一方法相似
wk = xw.books.add()

2、 打开Excel文档

# 支持绝对路径和相对路径
wb = app.books.open('filepath')
wk = xw.Book('filepath')
wk = xw.books.open('filepath')
# 练习的时候建议直接用下面这条
# wb = xw.Book('example.xlsx')
# 这样的话就不会频繁打开新的Excel

3、打开未储存或未关闭的excel实例

wk = xw.Book('Book1')    
wk = xw.books['Book1']  #也可以使用索引

如果在两个Excel实例中打开了相同的文件,则需要完全限定它并包含应用程序实例。

您将通过xw.apps.keys()找到您的应用实例密钥(PID):

xw.apps[10559].books['FileName.xlsx']
查看所有的实例进程:
xw.apps.keys() #输出list
kill所有的实例进程:
for i in xw.apps.keys():
  i = 'taskkill/pid ' + str(i) + ' -t -f'     
  os.system(i)

4、打开活动的工作簿

wb = xw.books.active
# 保存工作簿,若未指定路径,保存在当前工作目录。
wb.save(path=None)
#在没有保存的情况下关闭。
wk.close()  

7、退出Excel

app.quit()

(四)工作表

1、打开工作表

# 可以用名字也可以用索引
sheet = xw.books['工作簿的名字'].sheets['sheet的名字']
sheet = xw.books['工作簿的名字'].sheets[0]

2、打开活动工作表

sheet = xw.sheets.active

3、返回sheet指定的book

book_name = sheet.book

4、返回一个range对象,表示sheet上所有的单元格

sheet_cells = sheet.cells

5、获取或设置Sheet的名称

sheet.name
# 返回所有的工作表特定名称。
sheet_names_list = sheet.names

6、获取sheet中的所有图表集合

sheet.charts

7、清空表中所有数据和格式。

sheet.clear()

8、清除工作表的内容,但保留格式

sheet.clear_contents()

9、删除工作表

sheet.delete()

10、返回表索引(与excel相同)

sheet.index

11、创建一个新的Sheet并使其成为活动工作表

wb.sheets.add(name=None, before=None, after=None) 
name(str,default None) - 新工作表的名称。 如果为None,则默认为Excel的name.
before (Sheet, default None) - 一个对象,指定在新工作表添加之前的added.
after (Sheet, default None) - 指定工作表之后的新工作表的对象。

12、在整个工作表上自动调整列,行或两者的宽度

sheet.autofit(axis=None) 
# 参数:
axis (string, default None)
要自动调整行, 使用以下之一: rows 或 r,
要自动调整列, 使用以下之一: columns h c,
要自动调整行和列, 不提供参数

13、获取excel sheet多少行多少列

app = xw.App(visible=False, add_book=False)
xls = app.books.open(excel_file)
sheet = xls.sheets[0]
last_cell = sheet.used_range.last_cell
nrows = sheet.used_range.last_cell.row
ncols = sheet.used_range.last_cell.colum

(五)单元格

1、引用A1单元格

rng = xw.books['工作簿的名字'].sheets['sheet的名字'].range('A1')
sheet=xw.books['工作簿的名字'].sheets['sheet的名字']
rng=sheet.range('A1')

2、引用活动工作表上的单元格

# 注意Range首字母大写
rng=xw.Range('A1')
其中需要注意的是单元格的完全引用路径是:
# 第一个Excel程序的第一个工作薄的第一张sheet的第一个单元格
xw.apps[0].books[0].sheets[0].range('A1')
迅速引用单元格的方式是
sht=xw.books['名字'].sheets['名字']
# A1单元格
rng=sht[’A1']
rng=sht['a1']
# A1:B5单元格
rng=sht['A1:B5']
# 第一行的第一列即a1
rng=sht[0,0] 
# B1单元格
rng=sht[0,1]

3、引用区域单元格

# A1:J10
rng=sht[:10,:10]
# A1:E10
rng=sht[:10,:5]
rng=sht.range('a1:a5')
#rng = sht['a1:a5']
#rng = sht[:5,0]

4、对于单元格也可以用表示行列的tuple进行引用

# A1单元格的引用
xw.Range(1,1)
#A1:C3单元格的引用
xw.Range((1,1),(3,3))

(六)写入数据

1、写入单个值

# 注意".value“
sht.range('A1').value=1

2、写入列表

默认按行插入

# 将列表[1,2,3]储存在A1:C1中
sht.range('A1').value=[1,2,3]
# 等同于
sht.range('A1:C1').value = [1,2,3]
# 将列表[1,2,3]储存在A1:A3中
sht.range('A1').options(transpose=True).value=[1,2,3]
一维列表:
表示Excel中行或列的范围作为简单列表返回,
这意味着一旦它们在Python中,您就丢失了有关方向的信息。
如果这是一个问题,下一点将向您展示如何保留此信息:
######################## 列方向(嵌套列表)################
列表中,每个元素都已列表方式保存,存储时,是按照列方向保存的
sht = xw.Book().sheets[0]
sht.range('A1').value = [[1],[2],[3],[4],[5]]  # 列方向(嵌套列表)
sht.range('A1:A5').value
[1.0, 2.0, 3.0, 4.0, 5.0]
################## 行方向,普通列表 #######################
sht.range('A1').value = [1, 2, 3, 4, 5]
sht.range('A1:E1').value
[1.0, 2.0, 3.0, 4.0, 5.0]    
要强制单个单元格作为列表到达,请使用:
sht.range('A1').options(ndim=1).value
[1.0]

多行输入就要用二维列表

# 将2x2表格,即二维数组,储存在A1:B2中,如第一行1,2,第二行3,4 sht.range('A1').options(expand='table').value=[[1,2],[3,4]]

(七)读取数据

1、读取单个值

# 将A1的值,读取到a变量中
a=sht.range('A1').value

2、读取范围的值

  • 返回的值是列表形式,多行多列为二维列表。
  • 但有一点要注意,返回的数值默认是浮点数
  • #将第一行的值,即将A1到A2的值,读取到a列表中
    a=sht.range('A1:A2').value
    # 将第一行和第二行的数据按二维数组的方式读取
    a=sht.range('A1:B2').value
    

    3、读取Excel表格的行、列

  • 读取excel的第一列,先计算单元格的行数
  • 通过这种方法统计的工作区域的行或者列,不能被空值分隔
  • 空值分隔后面的区域,不在统计范围内。
  • 更好的方式是通过last_cell方式获取最下边且最右边的一个单元格。
  • last_cell = sheet.used_range.last_cell
  • last_row = last_cell.row
  • last_col = last_cell.column
  • 读取excel的第一列,先计算单元格的行数
    - 读取excel的第一列,先计算单元格的行数
    - 通过这种方法统计的工作区域的行或者列,不能被空值分隔
    - 空值分隔后面的区域,不在统计范围内。
    - 更好的方式是通过last_cell方式获取最下边且最右边的一个单元格。
    # 获取工作表的活动区域
    rng = sht.range('a1').expand('table')
    # 获取活动区域的行数
    nrows = rng.rows.count
    # 接着就可以按准确范围读取了
    a = sht.range(f'a1:a{nrows}').value
    
    同理选取一行的数据也一样
    ncols = rng.columns.count
    fst_col = sht[0,:ncols].value
    
    获取行数、列数,更好且更准确的方法
    # 更好的方式是通过last_cell方式获取最下边且最右边的一个单元格。
    last_cell = sheet.used_range.last_cell
    last_row = last_cell.row
    last_col = last_cell.column
    

    (八)常用函数和方法

    1、Book 工作簿常用的api

    # 新建工作簿
    xw.books.add()
    # 引用当前活动工作簿
    xw.books.active
    wb=xw.books[‘工作簿名称']
    wb.activate()激活为当前工作簿
    wb.fullname 返回工作簿的绝对路径
    wb.name 返回工作簿的名称
    wb.save(path=None) 保存工作簿,默认路径为工作簿原路径,若未保存则为脚本所在的路径
    wb.close() 关闭工作簿
    代码例子:
    # 引用Excel程序中,当前的工作簿
    wb=xw.books.acitve
    # 返回工作簿的绝对路径
    x=wb.fullname
    # 返回工作簿的名称
    x=wb.name
    # 保存工作簿,默认路径为工作簿原路径,若未保存则为脚本所在的路径
    x=wb.save(path=None)
    # 关闭工作簿
    x=wb.close()
    

    2、sheet 常用的api

    # 新建工作表
    xw.sheets.add(name=None,before=None,after=None)
    # 引用当前活动sheet
    xw.sheets.active
    # 引用某指定sheet
    sht=xw.books['工作簿名称'].sheets['sheet的名称']
    # 激活sheet为活动工作表
    sht.activate()
    # 清除sheet的内容和格式
    sht.clear()
    # 清除sheet的内容
    sht.contents()
    # 获取sheet的名称
    sht.name
    # 删除sheet
    sht.delete
    

    3、range常用的api

    # 引用当前活动工作表的单元格
    rng=xw.Range('A1')
    # 加入超链接
    # rng.add_hyperlink(r'www.baidu.com','百度',‘提示:点击即链接到百度')
    # 获得range的超链接
    rng.hyperlink
    # 取得当前range的地址
    rng.address
    rng.get_address()
    # 获得单元格的绝对地址
    rng.get_address(row_absolute=True, column_absolute=True,include_sheetname=False, external=False)
            workbook_file_path = os.path.join(os.getcwd(), "workbook", file_name)
            # 工作簿当前目录
            workbook_dir_path = os.path.dirname(workbook_file_path)
            # 如果不存在目录路径,就创建
            if not os.path.exists(workbook_dir_path):
                # 创建工作簿路径,makedirs可以创建级联路径
                os.makedirs(workbook_dir_path)
            # 如果不存在,Excel工作簿文件,就创建工作簿
            if not os.path.exists(workbook_file_path):
                # 打开Excel程序,APP程序(即Excel程序)不可见,只打开不新建工作薄,屏幕更新关闭
                app = xlwings.App(visible=False, add_book=False)
                # Excel工作簿显示警告,不显示
                app.display_alerts = False
                # 工作簿屏幕更新,不更新
                app.screen_updating = False
                # 创建工作簿
                wb = app.books.add()
                # 保存工作簿,若未指定路径,保存在当前工作目录。
                wb.save(workbook_file_path)
                # 关闭工作簿
                wb.close()
                # 退出Excel
                app.quit()
        # 读取工作簿全部内容,返回二维列表
        @staticmethod
        def workbook_read(file_name=__file_name, sheet_name=__sheet_name):
            # 工作簿文件路径
            workbook_file_path = os.path.join(os.getcwd(), "workbook", file_name)
            # 如果文件存在,就执行
            if os.path.exists(workbook_file_path):
                # 打开Excel程序,APP程序(即Excel程序)不可见,只打开不新建工作薄,屏幕更新关闭
                app = xlwings.App(visible=False, add_book=False)
                # Excel工作簿显示警告,不显示
                app.display_alerts = False
                # 工作簿屏幕更新,不更新
                app.screen_updating = False
                # 打开工作簿
                wb = app.books.open(workbook_file_path)
                # 获取活动的工作表
                sheet = wb.sheets[sheet_name]
                # 获取已编辑的矩形区域,最底部且最右侧的单元格
                last_cell = sheet.used_range.last_cell
                # 最大行数
                last_row = last_cell.row
                # 最大列数
                last_col = last_cell.column
                # 读取二维列表
                # 注释:如果含有 .options(expand='table').value 参数,空值隔断的部分,不会被读取
                # data = sheet.range((1, 1), (last_row, last_col)).options(expand='table').value
                # 读取二维列表
                data = sheet.range((1, 1), (last_row, last_col)).value
                # 关闭工作簿
                wb.close()
                # 退出Excel
                app.quit()
                return data
        # 写入二维列表,追加模式
        @staticmethod
        def workbook_append(data: list = None, file_name=__file_name, sheet_name=__sheet_name):
            # 工作簿文件路径
            workbook_file_path = os.path.join(os.getcwd(), "workbook", file_name)
            # 如果工作簿不存在,就创建工作簿
            if not os.path.exists(workbook_file_path):
                ToolExcel.workbook_new()
            # 如果文件存在,就执行
            if os.path.exists(workbook_file_path):
                # 打开Excel程序,APP程序(即Excel程序)不可见,只打开不新建工作薄,屏幕更新关闭
                app = xlwings.App(visible=False, add_book=False)
                # Excel工作簿显示警告,不显示
                app.display_alerts = False
                # 工作簿屏幕更新,不更新
                app.screen_updating = False
                # 打开工作簿
                wb = app.books.open(workbook_file_path)
                # 获取活动的工作表
                sheet = wb.sheets[sheet_name]
                # 获取已编辑的矩形区域,最底部且最右侧的单元格
                last_cell = sheet.used_range.last_cell
                # 最大行数
                last_row = last_cell.row
                # 写入二维列表,追加模式
                sheet.range((last_row + 1, 1)).options(expand='table').value = data
                # # 保存文件,保存以后重新读取单元格,重新获取所有活动区域的cell.
                # # 是否保存, 有待考证?
                # wb.save()
                # 获取已编辑的矩形区域,最底部且最右侧的单元格
                last_cell = sheet.used_range.last_cell
                # 最大行数
                last_row = last_cell.row
                # 最大列数
                last_col = last_cell.column
                # 在range中,cell的大小自适应
                sheet.range((1, 1), (last_row, last_col)).columns.autofit()
                # 保存文件
                wb.save()
                # 关闭工作簿
                wb.close()
                # 退出Excel
                app.quit()
        # 写入二维列表,重写模式
        @staticmethod
        def workbook_rewrite(data: list = None, file_name=__file_name, sheet_name=__sheet_name):
            # 工作簿文件路径
            workbook_file_path = os.path.join(os.getcwd(), "workbook", file_name)
            # 如果工作簿不存在,就创建工作簿
            if not os.path.exists(workbook_file_path):
                ToolExcel.workbook_new()
            # 如果文件存在,就执行
            if os.path.exists(workbook_file_path):
                # 打开Excel程序,APP程序(即Excel程序)不可见,只打开不新建工作薄,屏幕更新关闭
                app = xlwings.App(visible=False, add_book=False)
                # Excel工作簿显示警告,不显示
                app.display_alerts = False
                # 工作簿屏幕更新,不更新
                app.screen_updating = False
                # 打开工作簿
                wb = app.books.open(workbook_file_path)
                # 获取活动的工作表
                sheet = wb.sheets[sheet_name]
                # 清除sheet的内容和格式
                sheet.clear()
                # 写入二维列表,重写模式
                sheet.range("A1").options(expand='table').value = data
                # 获取已编辑的矩形区域,最底部且最右侧的单元格
                last_cell = sheet.used_range.last_cell
                # 最大行数
                last_row = last_cell.row
                # 最大列数
                last_col = last_cell.column
                # 所有range的大小自适应
                sheet.range((1, 1), (last_row, last_col)).columns.autofit()
                # 保存文件
                wb.save()
                # 关闭工作簿
                wb.close()
                # 退出Excel
                app.quit()
    

    四、参考文献:

    xlwings使用教程
    https://blog.csdn.net/qq_37289115/article/details/106666073

    xlwings 中文文档