Python自动化办公:xlrd万字教程

f32401c382f21443b42dfc9b1beef214.gif


Hi,我是山月。

相信很多小伙伴学Python都是奔着自动化办公来的,特别是对每天都要和excel打交道的小伙伴们来说。

之后山月也会给大家分享一些python处理excel的知识,希望大家多多支持~

如果看过山月之前的文章:自学Python一年后,我有这些想说,会知道python处理excel的库有很多,比如xlrd,xlwt,xlwings,openpyxl,pandas等

虽然山月一直用的是openpyxl,但是考虑到很多小伙伴是刚开始学习这方面的内容。

因此山月会先通过一个更简单的库--xlrd,来给大家介绍一下excel的一些基本知识,以及python如何处理excel。

希望大家能跟着文章把知识点的代码手动输一遍,把xlrd库掌握透~

01

准备工作

1.1 xlrd基本介绍

xlrd作为python处理excel最简单最基本的一个库,它只能用来读取excel数据,不能用来写和修改excel数据。

官方文档https://xlrd.readthedocs.io/en/latest/

1.2 安装xlrd

1)到python官网下载相应的版本手动安装,比如xlrd 2.0.1版本:

ebeb1333dc0f9358ee92d471eac3020a.png

官网:https://pypi.org/project/xlrd/

2)推荐使用:在cmd命令提示符窗口用pip install xlrd进行安装,如果想安装指定版本比如1.2.0,则输入:pip install xlrd==1.2.0。

1.3 查看xlrd版本

在cmd窗口输入pip show xlrd,查看安装的xlrd版本:

c5ca1b02d1925f02f39191f37bc74f4c.png

山月安装的是1.2.0的版本。因为现在最新版本的xlrd只支持.xls文件,所以如果需要读取.xlsx文件的话,需要安装旧版本。

02

Excel的介绍

既然要处理excel,首先我们得了解一下excel。

2.1 工作薄与工作表

大家在日常使用里肯定听过工作薄与工作表,但也有些小伙伴可能至今还弄不清楚工作薄与工作表的区别。

工作薄:一个excel文件就是一个工作薄,一个工作簿由一个或多个工作表所组成,工作簿中最多可建立255个工作表。

工作表:是真正意义上我们常说的表格,每张工作表都是由单元格组成的。

2.2 单元格

单元格是由行(row)和列(column)交叉构成的,它是组成表格的最小单位,也可进行可合并和拆分。我们对单个数据的输入和修改都是在单元格中进行的。

每个单元格都有一个固定的编号,由所在行列的位置来决定。比如B3,指的是“B”列与第3行交叉位置上的单元格。

2.3 创建一个表格

山月创建了一个excel文件【xlrd实例文件.xlsx】,也就是一个工作薄:

7071920ebbc6cca525354f4cb3b933ff.png

我们打开这个工作薄:

520a978b9b7a4b15e1506d148a078821.png

它一共有两个工作表:绩效成绩工作表、绩效工资工作表。

其中我们可以看到页面下方有两个工作表名称,其中工作表绩效成绩的名称是绿色的,这表明绩效成绩工作表是我们的目前正在操作的工作表,也就是活动工作表

下面我们会基于这个excel文件来对xlrd进行深入的学习。

如果大家需要这个excel源文件的话,可以在公众号后台发送:【xlrd表格】。

03

xlrd的详解

3.1 导入xlrd 

import xlrd #导入模块

3.2 打开excel文件

#如果excel文件在当前py文件的同一目录下,直接输入excel文件名打开
data= xlrd.open_workbook("xlrd实例文件.xlsx")


#如果excel文件不在py文件目录下,用excel文件的绝对路径打开
data= xlrd.open_workbook("H:\\临时文件夹\\xlrd实例文件.xlsx")

由于山月的excel文件就在py文件的同一目录下,因此在下面的解说里,山月都是直接使用第一种方法打开。

大家在学习的过程里按照自己的环境来选择方法哈。

我们来看看data运行的结果是什么,代码:

import xlrd #导入模块

data= xlrd.open_workbook("xlrd实例文件.xlsx") #打开excel文件

print(data)

运行结果:

xlrd.book.Book object at 0x0000013C076207F0

也就是说我们返回了一个xlrd.book.Book对象。下面我们基于这个对象来具体的看看xlrd怎么操作excel。

3.3 获取工作表

1)获取工作薄里所有工作表信息

如果你想了解一个excel文件,第一件事应该干什么?是不是看看这个工作薄里有多少个工作表?又有哪些工作表?

import xlrd #导入模块
data= xlrd.open_workbook("xlrd实例文件.xlsx")   #打开excel文件

work_sheets = data.nsheets       #返回工作薄中所有工作表的数量
work_names = data.sheet_names()    #返回工作薄中所有工作表的名字

print(work_sheets)
print(work_names)

运行结果:

2
['绩效成绩', '绩效工资']

我们可以得出【xlrd实例文件.xlsx】文件里一共有两个工作表,它们的名字分别是:绩效成绩和绩效工资。

也许好学的你立马有了疑问:但是我处理文件的时候一般都是在具体的工作表上进行操作呀~

别着急,我们就来看看怎么获取具体的工作表。

2)获取具体工作表

一共有两种方法可以用来获取具体的工作表:

通过工作表的索引顺序(sheet_index)来获取,或者通过工作表的名称(sheet_name)来获取,其中通过索引顺序有两种表达方式。

work_sheet = data.sheets()[sheet_index]     #通过工作表的索引顺序获取
work_sheet = data.sheet_by_index(sheet_index) #通过工作表的索引顺序获取
work_sheet = data.sheet_by_name(sheet_name) #通过工作表的名称获取

工作表索引也就是这个工作表在工作薄的位置(从0开始),比如我们绩效成绩工作表的索引是0,绩效工资工作表的索引是1。

我们来具体的看看怎么获得绩效成绩这个工作表:

import xlrd #导入模块
data= xlrd.open_workbook("xlrd实例文件.xlsx")   #打开excel文件

work_sheet_1 = data.sheets()[0]   

work_sheet_2 = data.sheet_by_index(0) 

work_sheet_3 = data.sheet_by_name('绩效成绩') 

print(work_sheet_1)
print(work_sheet_2)
print(work_sheet_3)

运行结果:

<xlrd.sheet.Sheet object at 0x000002B045863A58>
<xlrd.sheet.Sheet object at 0x000002B045863A58>
<xlrd.sheet.Sheet object at 0x000002B045863A58>

返回的结果是一个xlrd.sheet.Sheet对象

另外如果我们工作表的内容很多的话,我们应该要检查一下这个工作表是否已经完全导入了。检查的方法如下:

check = data.sheet_loaded(sheet_name) #通过工作表名称指定工作表进行检查
check = data.sheet_loaded(sheet_index) #通过工作表索引顺序指定工作表进行检查

比如我们需要检查绩效成绩这个工作表是否导入:

import xlrd #导入模块
data= xlrd.open_workbook("xlrd实例文件.xlsx")   #打开excel文件

check = data.sheet_loaded('绩效成绩') # 检查绩效成绩工作表是否导入完毕,完毕则返回true
print(check)

运行结果:

True

好啦,我们要处理的工作表已经得到啦,恭喜大家5d78b6723a877e76305e9117fc415382.png75874f8bd95cb2aa786bbb09966cffe3.pnge194ede44f65c92a632ea0d5c1576554.png接下来就是看具体的表格操作了~

3.4 具体内容的操作

注意:山月是以【绩效成绩】工作表为例来给大家分享,它的内容如下:

03f958da66113ad27d3440fbf71931d9.png

1)获取工作表名称

我们先来看看现在的工作表是不是我们想要的绩效成绩工作表:

import xlrd #导入模块
data= xlrd.open_workbook("xlrd实例文件.xlsx")   #打开excel文件
work_sheet = data.sheet_by_name('绩效成绩')  #获取工作表

sheet_name = work_sheet.name  #获取工作表名称
print(sheet_name)

运行结果:

绩效成绩

没错,就是我们要的结果。

2)工作表里行(row)的操作

①获取工作表中的有效行数

all_rows = work_sheet.nrows

②获取指定行所有单元格对象组成的列表

有两种表达方式:其中row_number是指定的行数(从0开始计算),返回的列表里是键值对。

row_object = work_sheet.row(row_number)  
row_object = work_sheet.row_slice(row_number)

③获取指定行单元格内容组成的列表

获取指定行所有单元格内容组成的列表,row_number为行数(从0开始计算):

row_content = work_sheet.row_values(row_number)

也可以用切片的方式获取指定行里指定从开始列(start_colx,包括)到结束列(end_colx,不包括)的内容组成的列表。

如果没有设置,默认start_colx=0,end_colx=None,end_colx为None表示结束没有限制。

row_content = work_sheet.row_values(row_number, start_colx=0, end_colx=None)

④获取指定行单元格数据类型组成的列表

其中:row_number为行数(从0开始计算),返回的列表是个逻辑值列表,同样可以用切片方式指定列数范围。

row_type = work_sheet.row_types(row_number)

至于逻辑值是什么,我们首先来了解一下常用的单元格的数据类型

  • 0:empty

  • 1:text

  • 2:number

  • 3:date

  • 4 :boolean

  • 5:error

也就是说若单元格数据类型为empy(空)则逻辑值为0。

⑤获取指定行有效单元格的长度

即获取这一行有多少个数据,row_number为行数(从0开始计算)。

row_length = work_sheet.row_len(row_number)

⑥获取工作表所有行的生成器

rows_generator = work_sheet.get_rows()

知识点:生成器对象是一个可迭代的一个对象,可以用list函数把它转换成列表。

⑦实例

import xlrd #导入模块
data= xlrd.open_workbook("xlrd实例文件.xlsx")   #打开excel文件
work_sheet = data.sheet_by_name('绩效成绩')  #获取工作表

all_rows = work_sheet.nrows  #获取工作表中的有效行数
print(all_rows)

row_object = work_sheet.row_slice(1)  #获取第2行所有单元格对象组成的列表
print(row_object)

row_content = work_sheet.row_values(1) #获取第2行所有单元格内容组成的列表
print(row_content)

row_content = work_sheet.row_values(1, start_colx=1, end_colx=2) #获取第2行里第2列单元格内容组成的列表
print(row_content)

row_type = work_sheet.row_types(1)  #获取第2行单元格数据类型组成的列表
print(row_type)

row_length = work_sheet.row_len(1)  #获取第2行有效单元格的长度
print(row_length)

rows_generator = work_sheet.get_rows() #获取工作表所有行的生成器对象
print(rows_generator)

list_generator = list(rows_generator)  #把生成器转换成列表
print(list_generator)

运行结果:

11
[text:'小红', number:2021001.0, number:98.0]
['小红', 2021001.0, 98.0]
[2021001.0]
array('B', [1, 2, 2])
3
<generator object Sheet.get_rows.<locals>.<genexpr> at 0x00000242CFE988B8>
[[text:'姓名', text:'工号', text:'成绩'], [text:'小红', number:2021001.0, number:98.0], [text:'小橙', number:2021002.0, number:100.0], [text:'小黄', number:2021003.0, number:90.0], [text:'小绿', number:2021004.0, number:72.0], [text:'小青', number:2021005.0, number:88.0], [text:'小蓝', number:2021006.0, number:60.0], [text:'小紫', number:2021007.0, number:86.0], [text:'小黑', number:2021008.0, number:60.0], [text:'小白', number:2021009.0, number:76.0], [text:'小彩', number:2021010.0, number:100.0]]

3)工作表里列(column)的操作

列的操作和行的操作是类似的,只是列的操作由row变成了col,我们直接来看例子:

import xlrd #导入模块
data= xlrd.open_workbook("xlrd实例文件.xlsx")   #打开excel文件
work_sheet = data.sheet_by_name('绩效成绩')  #获取工作表

all_cols = work_sheet.ncols  #获取工作表中的有效列数
print(all_cols)

col_object = work_sheet.col_slice(1)  #获取第2列所有单元格对象组成的列表
print(col_object)

col_content = work_sheet.col_values(1) #获取第2列所有单元格内容组成的列表
print(col_content)

col_content = work_sheet.col_values(1, start_rowx=1, end_rowx=2) #获取第2列里第2行单元格内容组成的列表
print(col_content)

col_type = work_sheet.col_types(1)  #获取第2列单元格数据类型组成的列表
print(col_type)

运行结果:

3
[text:'工号', number:2021001.0, number:2021002.0, number:2021003.0, number:2021004.0, number:2021005.0, number:2021006.0, number:2021007.0, number:2021008.0, number:2021009.0, number:2021010.0]
['工号', 2021001.0, 2021002.0, 2021003.0, 2021004.0, 2021005.0, 2021006.0, 2021007.0, 2021008.0, 2021009.0, 2021010.0]
[2021001.0]
[1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]

4)工作表里单元格的操作

①获取指定单元格内容

cell_value = work_sheet.cell(rowx, colx).value
cell_value = work_sheet.cell_value(rowx, colx)
cell_value = work_sheet.row(rowx)[colx].value

其中rowx为指定行,colx为指定列,(rowx, colx)为rowx+1行和colx+1列构成的单元格。

比如(1,1)是第2行第2列这个位置的单元格(B2单元格),即下图红框所示位置。

597d0157c0a67d779fd4e587d6ac5ea9.png

②获取指定单元格对象

返回的是一个列表,列表里是键值对:

cell_object = work_sheet.cell(rowx, colx)

③获取指定单元格数据类型 

数据类型同上:

0 - empty, 1 - text,  2 - number,  3 - date,  4 - boolean,  5 - error

cell_type = work_sheet.cell_type(rowx, colx)

④获取指定单元格内容的类型

注意这是单元格内容的类型,比如内容是数值,则是判断这个数值的类型:

cell_content_type = type(work_sheet.cell_value(rowx, colx))

⑤实例

我们以B2这个单元格为例来综合看看:

import xlrd #导入模块
data= xlrd.open_workbook("xlrd实例文件.xlsx")   #打开excel文件
work_sheet = data.sheet_by_name('绩效成绩')  #获取工作表

cell_value = work_sheet.cell_value(1, 1) #获取B2单元格内容
print(cell_value)

cell_object = work_sheet.cell(1, 1)  #获取B2单元格对象
print(cell_object)

cell_type = work_sheet.cell_type(1, 1)  #获取B2单元格数据类型 
print(cell_type)

cell_content_type = type(work_sheet.cell_value(1, 1))  #获取B2单元格内容的类型
print(cell_content_type)

运行结果:

2021001.0
number:2021001.0
2
<class 'float'>

04

实例

1、文件

用我们之前创建的:xlrd实例文件.xlsx,文件内容:

296744a30a98120bd505fa84dfd21b31.png

2、目标

我们如果认真看了文件的话,会发现每个员工的绩效工资是其对应的绩效成绩的10倍。100分的绩效成绩就是1000的绩效工资。

假如我们现在只有绩效成绩这一个表,要如何得出绩效工资表的内容?可以自己先想想你要如何做哦~

山月的想法:

  1. 读取绩效成绩工作表除表头以外的数据

  2. 把绩效成绩*10得到绩效工资

  3. 把绩效工资和对应的员工信息组成一组新的数据

  4. 写入表头后继续把新得到的数据写入,得到一个新的工作表,然后保存。

我们这篇文章只谈读取数据,写入数据的话下一篇文章再见。因此,我们只来看前三步。

3、代码实现

import xlrd #导入模块
data= xlrd.open_workbook("xlrd实例文件.xlsx")   #打开excel文件
work_sheet = data.sheet_by_name('绩效成绩')  #获取绩效成绩工作表

# 获取除表头外全部行内容
rows_generator = list(work_sheet.get_rows())[1:]

#创建个列表来储存名字、工号、绩效工资数据
row_list=[]

#利用for循环,得到名字、工号、绩效成绩
for rows in rows_generator:
    name, number, score = rows[0].value, rows[1].value, rows[2].value
    
    #利用绩效成绩得出绩效工资
    money = score*10 
    
    #把名字、工号和新得的绩效工资一起组成一个元组
    row_tuple=(name,number,money) 

    #把元组添加到之前建的列表里
    row_list.append(row_tuple) 

print(row_list) #打印列表

运行结果:

[('小红', 2021001.0, 980.0), ('小橙', 2021002.0, 1000.0), ('小黄', 2021003.0, 900.0), ('小绿', 2021004.0, 720.0), ('小青', 2021005.0, 880.0), ('小蓝', 2021006.0, 600.0), 
('小紫', 2021007.0, 860.0), ('小黑', 2021008.0, 600.0), ('小白', 2021009.0, 760.0), ('小彩', 2021010.0, 1000.0)]

完成啦~9f2402f2f564fa3e6a14b9d30c3ef724.pngfe6cd32846989b63e4b89a7bb93d22dd.png412fe377354b47fb9bd67aa02f9cab99.png

05

问题集锦

5.1 实战问题

不知道大家有没有发现一个问题:如果单元格里是数值类型,那返回的值自带小数点。比如小红的工号是2021001,返回的值为2021001.0。

那要怎么办呢?山月提供了两个解决方法:

1)在表格里是数值的单元格内容前加一个英文的单引号,把它变成以文本形式储存的数字。

94b85da0f3203f0d0869ecdce744f05b.png

2)通过代码判断单元格内容是否为浮点型

比如针对工号,解决代码:

import xlrd #导入模块
data= xlrd.open_workbook("xlrd实例文件.xlsx")   #打开excel文件
work_sheet = data.sheet_by_name('绩效成绩')  #获取绩效成绩工作表

col_content = work_sheet.col_values(1)[1:] #获取第2列除表头外的所有单元格数据组成的列表
print(col_content)

print('解决后的结果:')

for i in range(len(col_content)):
    if col_content[i] % 1 == 0.0:  #判断数据是否为浮点型
            col_content[i] = int(col_content[i])  # 浮点转成整型

print(col_content)

运行结果:

[2021001.0, 2021002.0, 2021003.0, 2021004.0, 2021005.0, 2021006.0, 2021007.0, 2021008.0, 2021009.0, 2021010.0]
解决后的结果:
[2021001, 2021002, 2021003, 2021004, 2021005, 2021006, 2021007, 2021008, 2021009, 2021010]

5.2 拓展问题

这个问题我们本次例子中没有遇到,但这是一个非常常见的问题,山月在学习得时候就遇到过。

问题:如果遇到日期格式的数据,xlrd不能直接读取。我们来看看例子。

有一个表格,它的内容如下:

d668651ecbc2a67739c64191db1070da.png

我们直接按照之前讲的方法来读取看看:

import xlrd #导入模块
data= xlrd.open_workbook("日期.xlsx")   #打开excel文件
work_sheet = data.sheet_by_index(0)  #获取工作表

col_content = work_sheet.col_values(0) #获取第1列所有单元格数据组成的列表
print(col_content)

col_type = work_sheet.col_types(0)  #获取第1列所有单元格数据类型组成的列表
print(col_type)

运行结果:

['日期', 44541.0, 44542.0, 44543.0, 44544.0, 44545.0, 44546.0, 44547.0, 44548.0]
[1, 3, 3, 3, 3, 3, 3, 3, 3]

根据结果来看,除了表头外,单元格的数据类型都是3,也就是日期格式,这个没有问题。

但是内容却不对了,比如A2这个单元格是2021-12-11,读出来却是44541.0。

这是因为Excel的日期是相对于基准日期(1900-01-01)为起点的天数数值。也就是说1900-01-01是1,1900-01-02是2...相应的2021-12-11是44541。

知识点:在python里一共有两个时间基准。0代表以1900-01-01为基准,1代表以1904-01-01为基准,一般使用1900-01-01为基准。

而对于日期的读取,xlrd有两种解决方法。

方法一:xlrd.xldate_as_tuple(xldate,datemode)

  • 参数 xldate表示要处理的单元格值

  • 参数 datemode 表示时间基准,也就是0或1。

date_cell = xlrd.xldate_as_tuple(work_sheet.cell_value(rowx, colx), 0) #以基准1900-01-01读取指定单元格,rowx为指定单元格行数,colx为指定单元格列数

它会返回一个元组:(年, 月, 日, 时, 分, 秒)。

当然,我们最终是要得到日期,所以要把自动填补的时间去掉。由于它是个元组,所以我们能利用索引轻易的得到对应的日期。

以A2单元格为例:

import xlrd #导入模块
data= xlrd.open_workbook("日期.xlsx")   #打开excel文件
work_sheet = data.sheet_by_index(0)  #获取工作表

date_cell = xlrd.xldate_as_tuple(work_sheet.cell_value(1, 0), 0) #读取A2单元格
print(date_cell)

date_cell_finally = '%d-%d-%d' %(date_cell[0],date_cell[1],date_cell[2]) #利用索引得到对应的年月日,并用-连接
print(date_cell_finally)

运行结果:

(2021, 12, 11, 0, 0, 0)
2021-12-11


方法二:xlrd.xldate.xldate_as_datetime(xldate,datemode)

同样,它的参数 xldate表示要处理的单元格值,参数 datemode 表示时间基准,也就是0或1。

date_cell = xlrd.xldate.xldate_as_datetime(work_sheet.cell(rowx,colx).value, 0) #以基准1900-01-01读取指定单元格,rowx为指定单元格行数,colx为指定单元格列数

它会返回一个datetime对象,格式是:年-月-日 时:分:秒。

对于这个对象,我们可以用strftime来处理,把它转化成指定格式的字符串。

对日期和时间进行格式化的符号:

435a5f279013fb7a7fdd92ff7e8c9429.png

同样对于A2单元格,我们想得到它对应的日期:

import xlrd #导入模块
data= xlrd.open_workbook("日期.xlsx")   #打开excel文件
work_sheet = data.sheet_by_index(0)  #获取工作表

date_cell = xlrd.xldate.xldate_as_datetime(work_sheet.cell(1,0).value, 0) #读取A2单元格
print(date_cell)

date_cell_finally = date_cell.strftime("%Y/%m/%d") #利用strftime转化成年/月/日
print(date_cell_finally)

运行结果:

2021-12-11 00:00:00
2021/12/11

好啦,今天的分享就到这,希望大家都能熟练的掌握xlrd的用法,以及通过这个学习,了解python处理excel的方法思路。

我们下次再见!

已经到底啦~(≧▽≦*)/~


 0872d2304b8cef16fb6e8ad172b9c479.png //  推荐阅读  // c11248dd3dfc55e1e92b716c4c9debf5.png

自学Python一年后,我有这些想说

2021-12-04

d87127199e4c7fcbb8f2865e7d36eacc.png

建议收藏:68个Python内置函数详解

2021-12-05

4aaf9e0b2938b997d5311da5f02b8100.png

初识Tkinter:一些必须掌握的基础知识

2021-12-09

99a84ca1c8b6cbb5fd874a5d93a124fc.png
  • 12
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值