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

2019年8月4日 / 69次阅读 / Last Modified 2019年8月4日

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

相关文章

    留言区

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


    前一篇:
    后一篇:

    More


    ©Copyright 麦新杰 Since 2019 Python笔记

    go to top