【python 让繁琐工作自动化】处理Excel电子表格

openpyxl模块打开

openpyxl.load_workbook('表格名称')函数——返回一个workbook类型的对象
:表格必须在当前工作目录,可以用os.chdir()更改当前工作目录

从工作簿(workbook)中获取工作表

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.rowc.column返回单元格的位置信息,从1开始;如 A1 的位置位 (1,1)
c.coordinate 返回以‘A1’格式表示的位置信息

c=sheet['A1']
print(c.row,c.column) #返回值1,1
print(c.coordinate)#返回值 A1

2. worksheetcell方法

传入两个整数作为单元格的rowcolumn,同样返回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_rowmax_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

对Worksheet切片

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)。
【python 让繁琐工作自动化】处理Excel电子表格_第1张图片
遍历这个区域中所有单元格的值:

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导入

创建并保存Excel文档

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即可设置字体样式

Font对象

关键字参数

关键字参数 数据类型 描述 关键字简写
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_dimensionscolumn_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')直接保存,不会导致原文件中的图表消失。

你可能感兴趣的:(笔记,python)