>>> from env_helper import info; info()
页面更新时间: 2023-04-15 21:51:22
运行环境:
Linux发行版本: Debian GNU/Linux 12 (bookworm)
操作系统内核: Linux-6.1.0-7-amd64-x86_64-with-glibc2.36
Python版本: 3.11.2
1.3. Python写入电子表格¶
我们可以使用openpyxl模块的 Workbook 函数来写入电子表格。
1.3.1. 创建工作簿与工作表¶
先来看一下如何实例化一个电子表格对象。
>>> from openpyxl import Workbook
>>> wb = Workbook()
这样就新建了一个新的工作表,这个工作薄可以保存以便其他程序使用。
若要指定只写模式,可以指定参数 write_only=True
。
在“只写”的情况下,可以访问工作簿与工作表, 但是没法访问单元格的信息。
一般打开电子表格时使用默认的可写可读模式就可以了。 在 OpenpyXL
可写可读模式下新建一个工作簿,会默认创建名为 Sheet
的表。 Excel
2016软件下新建的表默认名称为 Sheet1
。
sheetnames
属性可以查看电子表格中工作表名称的列表。旧版本中通过
get_sheet_names()
方法访问。
>>> wb.sheetnames
['Sheet']
工作表的名称可以修改,直接赋值就可以改工作表的名称:
>>> sheet = wb.active
>>> sheet.title = 'Sheet1'
新建一个工作表,可以指定索引,适当安排其在工作簿中的位置。
被安排到第二个工作表,index=0
就是第一个位置
>>> wb.create_sheet('Data', index=0)
>>> wb.create_sheet('Data2', index=1)
<Worksheet "Data2">
除了使用索引,也可以获取表格的名字。
或使用属性 sheetnames
:
>>> wb.sheetnames
['Data', 'Data2', 'Sheet1']
1.3.2. 删除工作表的方法¶
删除某个工作表,使用工作簿的方法 remove()
,或者直接使用 del
指令 del sheet
:
>>> wb.remove(sheet)
为了避免程序运行时出错,可以在删除工作表之前判断一下工作簿中是否有这个工作表:
>>> if sheet.title in wb.sheetnames:
>>> wb.remove(sheet)
1.3.3. 写入单元格¶
要在电子表格中写入值,直接针对单元格进行写入操作即可。 对行或列的写入,都可以通过循环完成。
要写入单元格,直接给单元格赋值就行:
>>> sheet['A1'] = 'good'
还可以使用公式。B9
处写入平均值:
>>> sheet['B2'] = '=AVERAGE(B2:B8)'
但是如果是读取的时候需要加上 data_only=True
这样读到 B9
返回的就是数字,如果不加这个参数,返回的将是公式本身’=AVERAGE(B2:B8)
’
通过对单元格的操作,可以实现新增数据,也可以实现更改数据。
1.3.4. 使用 append()
函数写入数据¶
要批量写入数据,可以使用遍历功能逐单元格写入。 另外, OpenpyXL 还提供了
append()
函数将列表写入到一行中。
根据函数名称,这个函数只能用来写入新的数据,不能实现更新数据的功能;
写入的数据,会自动判断空白行,然后在空白行中添加数据。
灵活使用逐入写入的功能,也可以实现按列写入的功能。
按行写入数据¶
可以一次添加多行数据,从现有表格最下面第一行空白行开始(下面都是空白行)写入。
>>> sheet['B2'] = None
添加一行
>>> row = [1 ,2, 3, 4, 5]
>>> sheet.append(row)
现在将表格中数据打开出来查看:
>>> for row in sheet.rows:
>>> for cell in row:
>>> if cell.value:
>>> pass
>>> else:
>>> cell.value = ''
>>> print( f'{cell.coordinate:3}:({cell.value:<4})', end=', ')
>>> print()
A1 :(good), B1 :( ), C1 :( ), D1 :( ), E1 :( ),
A2 :( ), B2 :( ), C2 :( ), D2 :( ), E2 :( ),
A3 :(1 ), B3 :(2 ), C3 :(3 ), D3 :(4 ), E3 :(5 ),
可以看到在最下面添加了一行数据。
要添加二维列表与之类似,通过遍历的功能实现:
>>> rows = [
>>> ['Num', 'd1', 'd2'],
>>> [2, 40, 30],
>>> [3, 40, 25],
>>> ]
>>> for row in rows:
>>> sheet.append(row)
>>> for row in sheet.rows:
>>> for cell in row:
>>> if cell.value:
>>> pass
>>> else:
>>> cell.value = ''
>>> print( f'{cell.coordinate:3}:({cell.value:<4})' , end=', ')
>>> print()
A1 :(good), B1 :( ), C1 :( ), D1 :( ), E1 :( ),
A2 :( ), B2 :( ), C2 :( ), D2 :( ), E2 :( ),
A3 :(1 ), B3 :(2 ), C3 :(3 ), D3 :(4 ), E3 :(5 ),
A4 :(Num ), B4 :(d1 ), C4 :(d2 ), D4 :( ), E4 :( ),
A5 :(2 ), B5 :(40 ), C5 :(30 ), D5 :( ), E5 :( ),
A6 :(3 ), B6 :(40 ), C6 :(25 ), D6 :( ), E6 :( ),
按列写入数据¶
由于 append
函数只能按行写入。如果我们想按列写入呢。append
能实现需求么? 如果把上面的列表嵌套看作矩阵。 只要将矩阵转置就可以了。
使用 zip()
函数可以实现,不过内部的列表变成了元组就是了。都是可迭代对象,不影响结果。
>>> list(zip(*rows))
[('Num', 2, 3), ('d1', 40, 40), ('d2', 30, 25)]
解释下上面的list(zip(*rows))
首先*rows
将列表打散,
相当于填入了若干个参数,zip
从某个列表中提取第1个值组合成一个tuple
,
再从每个列表中提取第2个值组合成一个tuple
,一直到最短列表的最后一个值提取完毕后结束,
更长列表的之后的值被舍弃,换句话,最后的元组个数是由原来每个参数(可迭代对象)的最短长度决定的。
比如现在随便删掉一个值,最短列表长度为2,data2
那一列(竖着看)的值全部被舍弃。
>>> rows = [
>>> ['Number', 'data1', 'data2'],
>>> [2, 40, 33],
>>> [3, 40, 25],
>>> ]
>>> wb.create_sheet('Data3', index=0)
<Worksheet "Data3">
>>> sheet = wb['Data3']
>>> for row in zip(*rows):
>>> sheet.append(row)
>>> for row in sheet.rows:
>>> for cell in row:
>>> if cell.value:
>>> pass
>>> else:
>>> cell.value = ''
>>> print( f'{cell.coordinate:3}:({cell.value:<6})' , end=', ')
>>> print()
A1 :(Number), B1 :(2 ), C1 :(3 ),
A2 :(data1 ), B2 :(40 ), C2 :(40 ),
A3 :(data2 ), B3 :(33 ), C3 :(25 ),
最后zip
返回的是 zip
对象,看不到数据的。使用list转换下就好了。使用 zip
可以方便实现将数据按列写入。
1.3.5. 保存文件¶
所有的操作结束后,通过 save()
方法保存文件。这个函数的参数为要保存的文件路径或 PosixPath 对象
,后缀名为 xlsx
。
>>> wb.save('xx_example.xlsx')