openpyxl
模块打开openpyxl.load_workbook('表格名称')
函数——返回一个workbook
类型的对象
注:表格必须在当前工作目录,可以用os.chdir()
更改当前工作目录
1. get_sheet_names()
方法:获取工作簿中所有的表名,返回一个字符串列表
2. get_sheet_by_name('表名')
:返回一个worksheet
对象,用来表示表名所指代的工作表
sheet=wb.get_sheet_by_name('Sheet1')#获取工作表
1.利用 sheet['A1']
直接访问:
c=sheet['A1']
返回cell
对象
cell
对象的属性
c.value
返回该单元格的内容
c.row
,c.column
返回单元格的位置信息,从1开始;如 A1 的位置位 (1,1)
c.coordinate
返回以‘A1’格式表示的位置信息
c=sheet['A1']
print(c.row,c.column) #返回值1,1
print(c.coordinate)#返回值 A1
2. worksheet
的cell
方法
传入两个整数作为单元格的row
和column
,同样返回cell
对象
c=sheet['A1']
也可以表示为sheet.cell(1,1)
或sheet.cell(row=1,column=1)
cell
方法方便利用循环对表值进行遍历。
wb=openpyxl.load_workbook('example.xlsx')
sheet=wb.get_sheet_by_name('Sheet1')
row=sheet.max_row
column=sheet.max_column
for i in range(1,row+1):
for j in range(1,column+1):
print(sheet.cell(i,j).value,end='\t')
print('\n')
遍历表格用下面的方法更为便利
for row in sheet:
for cell in row:
print(cell.value,end='\t')
print('\n')
注:在新版本的openpyxl
中获得worksheet
对象的最大高度和最大宽度是通过max_row
和max_column
来实现,书上的是:get_highest_row()
和get_highest_column()
原书写的是从openpyxl.cell
导入,但是openpyxl
更新之后需要从openpyxl.utils
导入
get_column_letter()——将数字转换成对应的字母,返回该列所对应的字母
column_index_from_string()——将字母转换成对应的数字,返回该列所对应的数字
import openpyxl
from openpyxl.utils import get_column_letter
from openpyxl.utils import column_index_from_string
print(get_column_letter(2)) #输出B
print(column_index_from_string('A')) #输出1
print(get_column_letter(98)) #输出CT
import os,openpyxl
wb=openpyxl.load_workbook('example.xlsx')
sheet=wb.get_sheet_by_name('Sheet1')
T=sheet['A1':'c3']
T=sheet['A1':'c3']
返回一个元组,元组包含三个元组,每个元组代表一行,这三个元组中的每一个元素代表一个单元格(Cell)。
遍历这个区域中所有单元格的值:
for row in T:
for cell in row:
print(cell.coordinate,':',cell.value)
print('---End of Row---')
输出:
A1 : 4/5/2015 1:34:02 PM
B1 : Apples
C1 : 73
---End of Row---
A2 : 4/5/2015 3:41:23 AM
B2 : Cherries
C2 : 85
---End of Row---
A3 : 4/6/2015 12:46:51 PM
B3 : Pears
C3 : 14
---End of Row---
假定你有一张电子表格的数据,来自于 2010 年美国人口普查。你有一个无聊的任务,要遍历表中的几千行,计算总的人口,以及每个县的普查区的数目(普查区就是一个地理区域,是为人口普查而定义的)。每行表示一个人口普查区。我们将这个电子表格文件命名为censuspopdata.xlsx,可以从 http://nostarch.com/automatestuff/下载它。
尽管 Excel 是要能够计算多个选中单元格的和, 你仍然需要选中 3000 个以上县的单元格。即使手工计算一个县的人口只需要几秒钟,整张电子表格也需要几个小时时间。
在这个项目中,你要编写一个脚本,从人口普查电子表格文件中读取数据,并 在几秒钟内计算出每个县的统计值。 下面是程序要做的事:
• 从 Excel 电子表格中读取数据。
• 计算每个县中普查区的数目。
• 计算每个县的总人口。
• 打印结果。
这意味着代码需要完成下列任务:
• 用 openpyxl
模块打开 Excel 文档并读取单元格。
• 计算所有普查区和人口数据,将它保存到一个数据结构中。
• 利用 pprint
模块可以把字典转换成字符串,将该数据结构写入一个扩展名为.py的文本文件。
import os,openpyxl,pprint
os.chdir('D:/python/python编程快速上手-让繁琐的工作自动化/处理excel电子表格')
print('Opening Workbook……')
wb=openpyxl.load_workbook('censuspopdata.xlsx')
sheet=wb.get_sheet_by_name('Population by Census Tract')
countyData={}
countyPop=0 ##记录总人口数
print('Reading Rows……')
for row in sheet['A2':'D'+str(sheet.max_row)]: ##读取表格中的每一行
State=row[1].value
county=row[2].value
pop=row[3].value ##记录每一个区的人口数
countyData.setdefault(State,{})
##设置每一个州的默认值,若字典中没有记录该州,则将当前State记录,并设置默认值为{},若有记录则不执行操作
countyData[State].setdefault(county,{'tracts':0,'pop':0})
#设置State每一个county 的分区和人口数据默认值,若字典中没有记录该county,则记录当前county,并设置默认值为{'tracts':0,'pop':0}
countyData[State][county]['tracts']+=1
countyData[State][county]['pop']+=pop#统计分区和人口
countyPop+=pop #统计总人口
print('Writing result……')
resultFile=open('census2010.py','w')
resultFile.write('AllData='+pprint.pformat(countyData))
resultFile.close()
print('Done.')
census.py文件可以通过代码访问
from census2010 import AllData
print(AllData['AK']['Anchorage'])#输出为{'pop': 291826, 'tracts': 55}
注:census.py必须在当前工作目录下才可以通过import
导入
opnpyxl.Workbook()
——创建一个新的空的Workbook对象
import os,openpyxl
os.chdir('D:/python/python编程快速上手-让繁琐的工作自动化/处理excel电子表格')
wb=openpyxl.Workbook()
sheetname=wb.get_sheet_names()
#返回工作簿中的表格名,新建工作簿中只有一个工作表,默认名称为Sheet
sheet=wb.get_sheet_by_name(sheetname[0])
print(sheet.title) #返回sheet所对应的表格的名称
对工作表执行改名操作:
sheet.title='Spam'
保存工作簿:wb.save(filename)
creat_sheet()
方法——返回一个新的worksheet对象,默认名称为sheetX(X=1-N),默认为工作簿的最后一个工作表,可以利用index和title关键字参数指定新的工作表的索引与名称。
import os,openpyxl
os.chdir('D:/资料/python/python编程快速上手-让繁琐的工作自动化/处理excel电子表格')
wb=openpyxl.Workbook()
wb.create_sheet(index=0,title='Spam')
wb.create_sheet()
sheetname=wb.get_sheet_names()
print(sheetname)##['Spam', 'Sheet', 'Sheet1']
remove_sheet(worksheet)
方法——接受一个worksheet对象作为参数(不是sheet的title),若知道要删除的工作表的名称,就可以利用get_sheet_by_name()
获得worksheet
对象,再将其传递给remove_sheet()
方法。
print(wb.get_sheet_names()) #['Spam', 'Sheet', 'Sheet1']
wb.remove_sheet(wb.get_sheet_by_name('Spam'))
print(wb.get_sheet_names()) #['Sheet', 'Sheet1']
类似于将值写入字典:
方法1:sheet['A1']='Hello World!'
方法2:sheet.cell(1,2).value='Hello Python'
import os,openpyxl
os.chdir('D:/python/python编程快速上手-让繁琐的工作自动化/处理excel电子表格')
wb=openpyxl.Workbook()
wb.create_sheet(index=0,title='Spam')
wb.create_sheet()
print(wb.get_sheet_names())
sheet=wb.get_sheet_by_name('Spam')
sheet['A1']='Hello World!'
sheet.cell(1,2).value='Hello Python'
print(sheet['A1'].value)
print(sheet['B1'].value)
wb.save('aaa.xlsx')
设置字体样式需要导入Font()
,
导入方法:from openpyxl.styles import Font
import openpyxl
from openpyxl.styles import Font
wb=openpyxl.Workbook()
sheet=wb.get_sheet_by_name('Sheet')
italic24Font=Font(size=24,italic=True) #返回Font对象
#size表示字号大小,italic表示斜体
sheet['A1']='Hello World!'
sheet['A1'].font=italic24Font #为单元格设置字体
wb.save('Font_test.xlsx')
italic24Font=Font(size=24,italic=True)
返回一个Font对象
注:书上使用了下面的方法来设置字体的样式
styleObj = Style(font = italic24Font)
sheet['A'].style/styleObj
openpyxl的后续版本有所修改,所以只需要使用sheet['A1'].font=italic24Font
即可设置字体样式
关键字参数
关键字参数 | 数据类型 | 描述 | 关键字简写 |
---|---|---|---|
name | 字符串 | 字体名称,如:"Times New Roman | 无 |
size | 整型 | 字体大小 | sz |
blod | 布尔型 | True表示粗体 | b |
italic | 布尔型 | True表示斜体 | 无 |
color | argb十六进制值 | 为字体设置颜色 | 无 |
underline | 字符串{‘doubleAccounting’, ‘singleAccounting’, ‘single’, ‘double’} | 设置下划线 | u |
…… | …… | …… | …… |
italic24Font=Font(sz=24,i=False,b=False,name='Times New Roma',color='00993366',underline='single')
sheet['A1']='24Times New Roma-bold-italic'
sheet['A1'].font=italic24Font #为单元格设置字体
import openpyxl
wb=openpyxl.Workbook()
sheet=wb.get_sheet_by_name('Sheet')
sheet['A1']=1
sheet['A2']=2
sheet['A3']=3
sheet['A4']='=SUM(A1:A3)'
wb.save('Font_test.xlsx')
将在Excel中输入的公式以字符串的格式传递给单元格
在直接读取单元格的值的时候sheet['A4'].value
会返回公式,即:=SUM(A1:A3)
,若想返回单元格的值,需要在加载文件时在load_workbook
函数中加上data_only=True
关键字参数,如:wb=openpyxl.load_workbook('Test-公式读取.xlsx',data_only=True)
。
wb=openpyxl.load_workbook('Test-公式读取.xlsx',data_only=True)
sheet=wb.get_sheet_by_name('Sheet1')
print(sheet['A4'].value) #返回6,真实值
以上代码打印结果为6,是单元格的真实值
但是是否返回单元格的真实值还取决于文件的来源; data_only = True
取决于Excel等应用程序缓存的公式的值。如果文件是由openpyxl
或类似的库创建的,则可能从未评估公式,因此,没有缓存值可用,因此此时即使加上了data_only=True
关键字参数,也不会打印单元格的真实值,而是 None 。例如,用前面测试公式的生成的文件 Font_test.xlsx 来测试一下:
wb=openpyxl.load_workbook('Font_test.xlsx',data_only=True)
sheet=wb.get_sheet_by_name('Sheet')
print(sheet['A4'].value)
此时的打印结果就是 None 而不是此处单元格所包含的真实内容。
总结:若文件由Excel等应用程序创建,则添加data_only=True
关键字参数sheet['A4'].value
就可以返回单元格的真实内容,反之则返回单元格中的公式。若文件由openpyxl
或类似的库创建,添加data_only=True
关键字参数sheet['A4'].value
会返回None,反之则返回单元格中的公式。
import openpyxl
wb=openpyxl.Workbook()
sheet=wb.get_sheet_by_name('Sheet')
sheet['A1']='Tall Row'
sheet['B2']='Wide column'
sheet.row_dimensions[1].height=70 ##设置行高
sheet.column_dimensions['B'].width=20 ##设置列宽
wb.save('Font_test.xlsx')
row_dimensions
和column_dimensions
分别包含RowDimensions对象和ColumnDimensions对象,row_dimensions中可以用行的数字编号来访问其中的某一行,得到RowDimensions对象,column_dimensions可以通过列的字母编号来访问其中的某一列,得到ColumnDimensions对象。
有了RowDimensions对象后就可以设置它的高度,范围为0-409之间的整数或者浮点数,默认行高为12.75;有了ColumnDimensions对象,就可以设置他的宽度,所设置的值为列宽的点数,1点等于1/72英寸,可设置的范围为0-255之间的整数或者浮点数。
利用worksheet的merge_cells()
方法可以合并单元格,参数为字符串,如:‘A1:D3’ 表示左上角和右下角单元格坐标。
要设置合并之后单元格的值,只需要设置左上角单元格的值;同样当一组单元格存在内容时,合并单元格只保存左上角的值(同Excel)。
import openpyxl
wb=openpyxl.Workbook()
sheet=wb.get_sheet_by_name('Sheet')
sheet.merge_cells('A1:D3')
sheet['A1']='12个单元格合并在一起'
wb.save('Font_test.xlsx')
利用worksheet的unmerge_cells()
方法可以合并单元格,参数与merge_cells()
方法相同
import openpyxl
wb=openpyxl.load_workbook('Font_test.xlsx')
sheet=wb.get_sheet_by_name('Sheet')
sheet.unmerge_cells('A1:D3')
wb.save('Font_test.xlsx')
拆分后,合并的单元格中的内容将储存在左上角单元格。
每个 Worksheet 对象都有一个 freeze_panes属性,可以设置为一个Cell 对象或一个单元格坐标的字符串,单元格上边的所有行和左边的所有列都会冻结,但单元格所在的行和列不会冻结。
要解冻所有的单元格,就将 freeze_panes 设置为 None 或’A1’。
示例:
import openpyxl
wb=openpyxl.load_workbook('produceSales.xlsx')
sheet=wb.get_sheet_by_name('Sheet')
sheet.freeze_panes='A2' #将第一行冻结,使第一行永远可见
wb.save('produceSales_副本.xlsx')
也可以通过下面的方式将第一行冻结
import openpyxl
wb=openpyxl.load_workbook('produceSales.xlsx')
sheet=wb.get_sheet_by_name('Sheet')
cell=sheet['A2']
sheet.freeze_panes=cell ##将 freeze_panes属性设置为一个Cell 对象
wb.save('produceSales_副本.xlsx')
要创建图表,需要做下列事情:
1.从一个矩形区域选择的单元格,创建一个 Reference 对象。
2.通过传入 Reference 对象,创建一个 Series 对象。
3.创建一个 Chart 对象。
4.将 Series 对象添加到 Chart 对象。
5.可选地设置Chart对象的top、left、width和height变量来设置图表的位置和大小
6.将 Chart 对象添加到 Worksheet 对象。
import openpyxl
wb=openpyxl.Workbook()
sheet=wb.get_sheet_by_name('Sheet')
for i in range(1,11):
sheet['A'+str(i)]=i
#创建表格内容
refObj = openpyxl.chart.Reference(sheet, min_row = 1, min_col = 1, max_row = 10, max_col = 1)
#传入sheet对象和单元格区域,创建一个Reference对象
seriesObj=openpyxl.chart.Series(refObj,title='First Series')
#传入reference对象,创建一个Series对象
chartObj=openpyxl.chart.BarChart()
#创建一个chart对象
chartObj.append(seriesObj)
#将series对象添加到chart对象
'''
chartObj.top=50
chartObj.left=100
# ##设置图表的位置
'''
chartObj.width=16
chartObj.height=10
##设置图表的大小
chartObj.title='Chart1'
#设置表格的标题,默认为series的标题
sheet.add_chart(chartObj,'C5') #C5为图表的位置,表示图表的右上角位置为C5
#将图表保存到worksheet
wb.save('Chart_test.xlsx')
openpyxl.chart.BarChart()创建一个条形图
openpyxl.chart.LineChart()创建一个折线图
openpyxl.chart.ScatterChart()创建一个散点图
openpyxl.chart.PieChart()创建一个饼图
注:Openpyxl的3.0.3版本已经支持加载Workbook的图表,通过wb=openpyxl.load_workbook('Chart_test.xlsx')
加载文件,再通过wb.save('Chart_test_1.xlsx')
直接保存,不会导致原文件中的图表消失。