用xlrd模块读取合并单元格(merged cell)

2019年8月4日 / 7,434次阅读 / Last Modified 2020年12月28日
excel表格

Python的第三方模块xlrd,用来读取.xls文件,从模块名就可以看出,只能用来读。本文介绍使用xlrd模块读取合并单元格(merged cells)的技巧。

请先学习:用xlrd模块读取.xls文件

测试用带合并单元格的.xls文件

文件名依然是xlrd_test.xls,合并单元格使用sheet 123:

合并单元格
合并单元格

excel文件的行是从1开始,列是从字母A开始。xlrd模块的行和列,都是从0开始,这比较符合程序员的思维。

读取合并单元格里的cell

测试.xls文件有一些cell本合并了,不过,我们还是试着读一下这些cell,请看下面的代码:

>>> book = xlrd.open_workbook('xlrd_test.xls')
>>> sh = book.sheet_by_name('123')
>>> sh.name
'123'
>>> sh.nrows
4
>>> sh.ncols
4
>>> sh.cell_value(1,0)
'2b'
>>> sh.cell_value(1,1)
''
>>> sh.cell_value(2,0)
'3c4d'
>>> sh.cell_value(2,1)
''
>>> sh.cell_value(3,0)
''
>>> sh.cell_value(3,1)
''
>>> sh.cell_value(2,2)
34.0
>>> sh.cell_value(3,2)
''
>>> sh.merged_cells
[]

这段代码先打开.xls文件,然后选择123 sheet,看看sheet的名称,行列数量,然后一个个将合并单元格的cell值都读取出来。我们可以发现一个规律,每一个合并单元格,只有左上角的那个cell(行列最小)能够读出值,其它cell都是empty。这就是xlrd模块读取合并单元格的特点。

获取merged_cells

上面的代码,merged_cells是一个空的list,现在我们来让它有内容:

>>> book = xlrd.open_workbook('xlrd_test.xls', formatting_info=True)
>>> sh = book.sheet_by_name('123')
>>> sh.merged_cells
[(1, 2, 0, 2), (2, 4, 2, 3), (2, 4, 0, 2)]

在打开.xls的open_workbook函数中,加入一个formatting_info=True这样的参数,这样就可以获得sheet的merged_cells信息。

merged_cells是一个list,list中每个元素是tuple,每个tuple又有4个值,仔细观察,这4个值分别是row和col的index。我们可以写一段代码,来遍历每个合并单元格里的cell:

>>> for merged in sh.merged_cells:
...     for i in range(merged[0],merged[1]):
...         for j in range(merged[2],merged[3]):
...             print(f'({i},{j})',sh.cell_value(i,j))
...
(1,0) 2b
(1,1)
(2,2) 34.0
(3,2)
(2,0) 3c4d
(2,1)
(3,0)
(3,1)

判断cell是否在合并单元格内

对于任意cell,我们只需要将其row和col值拿来跟merged_cells进行某种方式的比较,就可以判断这个cell是否在合并单元格内。请看如下代码:

>>> def inMerged(row,col):
...     for merged in sh.merged_cells:
...         if (row >= merged[0] and row < merged[1]
...            and col >= merged[2] and col < merged[3]):
...             return True
...     return False
...
>>> inMerged(1,0)
True
>>> inMerged(1,1)
True
>>> inMerged(1,2)
False
>>> inMerged(2,2)
True
>>> inMerged(3,2)
True
>>> inMerged(2,0)
True
>>> inMerged(2,1)
True
>>> inMerged(0,0)
False
>>> inMerged(0,1)
False

如何处理合并单元格里的空cell

从上面的内容,我们可以看到,合并单元格,只有左上角的那个cell能够读取到正常的值,其它cell的值都是空。我们也有了inMerged函数,来判断cell是否在合并单元格内。这些为空的cell,其实并不是正的empty,我们在处理excel文件的时候,他们都是有值的,只是因为值一样,为了方便处理,我们将其合并了。

我们可以写一点代码,来读取这些值为空的cell的真正的值:

>>> def cell_real_value(row,col):
...     for merged in sh.merged_cells:
...         if (row >= merged[0] and row < merged[1]
...             and col >= merged[2] and col < merged[3]):
...             return sh.cell_value(merged[0],merged[2])
...     return sh.cell_value(row,col)
...
>>> cell_real_value(1,0)
'2b'
>>> cell_real_value(1,1)
'2b'
>>> cell_real_value(2,2)
34.0
>>> cell_real_value(3,2)
34.0
>>> cell_real_value(2,0)
'3c4d'
>>> cell_real_value(2,1)
'3c4d'
>>> cell_real_value(3,0)
'3c4d'
>>> cell_real_value(3,1)
'3c4d'
>>> cell_real_value(0,0)
1.0
>>> cell_real_value(0,1)
'a'
>>> cell_real_value(0,2)
1.0
>>> cell_real_value(0,3)
'a'

cell_real_value函数的逻辑与inMerged一样,首先判断cell是否在某个合并单元格内,如果是,返回这个合并单元格左上角的那个cell的值,如果不是,直接调用cell_value() 函数获取值。因此,获取合并单元格内cell的类型等其它信息,也与此方法一致。

差不多了,以上即是对使用xlrd模块处理.xls文件中的合并单元格的介绍。

-- EOF --

本文链接:https://www.pynote.net/archives/744

留言区

《用xlrd模块读取合并单元格(merged cell)》有3条留言

您的电子邮箱地址不会被公开。 必填项已用*标注

  • jack

    这段话有些许错别字,还请作者帮忙纠正一下,“merged_cells是一个list,list中每隔元素时tuple,每隔tuple有4个值,仔细观察,这4个值分别是row和col的index。我们可以写一段下面的代码,来遍历每隔合并单元格里的cell:” [回复]

    • 麦新杰

      错别字已修正,谢谢.. [回复]

  • 李工

    我的想法是通过监测这个sheet有多少个合并单元格,而且通过检测到的单元格的数据在新建的表格中创建一个同样的表格,然后实现把这个原表格中的内容添加到新建的工作簿中的sheet中,最后实现自动化创建同样表格,同样格式的表格,填写不同的数据, [回复]


前一篇:
后一篇:

More

麦新杰的Python笔记

Ctrl+D 收藏本页


©Copyright 麦新杰 Since 2019 Python笔记

go to top