python excel数据处理

Python语言最近非常火,其丰富的模块支持使得开发软件的效率大大提高。本文我们就学习一下使用openpyxl进行Excel文档相关处理的功能。

Excel文档

首先,我们来看一些基本定义:Excel电子表格文档称为工作簿。单个工作簿保存在扩展名为.xlsx的文件中。每个工作簿可以包含多个工作表(也称为工作表)。用户当前正在查看的工作表(或在关闭Excel之前最后查看的工作表)称为活动工作表。

每个工作表都有列(由A开头的字母寻址)和行(从1开始的数字寻址)。特定列和行的框称为单元格。每个单元格可以包含数字或文本值。具有数据的单元格网格组成一张纸。

安装openpyxl模块

Python不附带OpenPyXL,因此您必须安装它。模块的名称是openpyxl。要测试是否正确安装,请在交互式shell中输入以下内容:

>>> import openpyxl

如果模块已正确安装,则不应生成错误消息。请记住openpyxl在本章中运行交互式shell示例之前导入模块,否则您将收到NameError: name 'openpyxl' is not defined错误。

操作步骤

作为快速理解,这里是从电子表格文件中读取单元格所涉及的所有函数,方法和数据类型的概述:

1. 导入openpyxl模块。

2. 调用openpyxl.load_workbook()功能。

3. 获取一个Workbook对象。

4. 读取active成员变量或调用get_sheet_by_name()工作簿方法。

5. 获取一个Worksheet对象。

6. 使用索引或通过row和column关键字参数调取sheet 中的cell()表方法。

7. 获取一个Cell对象。

8. 读取Cell对象的value属性。

读Excel文档

本章中的示例将使用存储在根文件夹中的名为test.xlsx的电子表格。您可以自己创建电子表格。图12-1显示了Excel自动为新工作簿提供的名为Sheet1,Sheet2和Sheet3的三个默认工作表的选项卡。(创建的默认工作表数量可能因操作系统和电子表格程序而异。)

图12-1。excel工作表的选项卡位于Excel

现在我们有了示例电子表格,让我们看看我们如何使用openpyxl模块来操作它。

使用OpenPyXL打开Excel文档

导入openpyxl模块后,您将能够使用该openpyxl.load_workbook()功能。在交互式shell中输入以下内容:

>>> import openpyxl

>>> wb = openpyxl.load_workbook('test.xlsx')

>>> type(wb)

'openpyxl.workbook.workbook.workbook'>

openpyxl.load_workbook()函数返回workbook数据类型的对象。

test.xlsx和程序在一个目录中,如果在其它目录里可以通过导入os模块,使用os.getcwd()获取当前目录,或通过os.chdir()更换目录。

从工作簿中获取表格

get_sheet_names()方法获取工作簿中所有工作表名称的列表。在交互式shell中输入以下内容:

>>> import openpyxl

>>> wb = openpyxl.load_workbook('test.xlsx')

>>> wb.get_sheet_names()

['Sheet1', 'Sheet2', 'Sheet3']

>>> sheet = wb.get_sheet_by_name('Sheet3')

>>> sheet

>>> type(sheet)

>>> sheet.title

'Sheet3'

>>> anotherSheet = wb.active

>>> anotherSheet

上面的代码 一目了然。得到Worksheet对象后可以通过title属性获取它的名称。

从Sheet中获取cell

获得Worksheet对象后,可以按名称访问Cell对象。在交互式shell中输入以下内容:

>>> import openpyxl

>>> wb = openpyxl.load_workbook('test.xlsx')

>>> sheet = wb.get_sheet_by_name('Sheet1')

>>> sheet['A1']

>>> sheet['A1'].value

datetime.datetime(2015, 4, 5, 13, 34, 2)

>>> c = sheet['B1']

>>> c.value

'Apples'

>>> 'Row ' + str(c.row) + ', Column ' + c.column + ' is ' + c.value

'Row 1, Column B is Apples'

>>> 'Cell ' + c.coordinate + ' is ' + c.value

'Cell B1 is Apples'

>>> sheet['C1'].value

73

Cell对象具有一个value属性,该属性包含存储在该单元格中的值。Cell对象还具有row,column和coordinate提供单元格位置信息的属性。

在这里,访问单元格B1 value的Cell对象属性为我们提供了字符串'Apples'。该row属性为我们提供了整数1,column属性给出了我们'B',coordinate属性给了我们'B1'。

OpenPyXL将自动解释A列中的日期,并将它们作为datetime值而不是字符串返回。逐个指定列可能很难编程,特别是因为在Z列之后,列开始使用两个字母:AA,AB,AC等。作为替代方案,您还可以使用工作表的cell()方法获取单元格,并为其row和column关键字参数传递整数。第一行或列整数1不是0。输入以下内容继续交互式shell示例:

>>> sheet.cell(row=1, column=2)

>>> sheet.cell(row=1, column=2).value

'Apples'

>>> for i in range(1, 8, 2):

print(i, sheet.cell(row=i, column=2).value)

1 Apples

3 Pears

5 Apples

7 Strawberries

正如您所看到的,使用工作表的cell()方法并传递它row=1并column=2获取Cell单元格的对象B1,就像指定sheet['B1']did一样。然后,使用该cell()方法及其关键字参数,您可以编写一个for循环来打印一系列单元格的值。

假设您想要下到B列并在每个具有奇数行号的单元格中打印该值。通过传递2的range()功能的“台阶”的参数,你可以从cell中每隔一行(在这种情况下,所有的奇数行)读取cell中的值。

您可以使用Worksheet对象max_row和max_column成员变量确定工作表的大小。在交互式shell中输入以下内容:

>>> import openpyxl

>>> wb = openpyxl.load_workbook('test.xlsx')

>>> sheet = wb.get_sheet_by_name('Sheet1')

>>> sheet.max_row

7

>>> sheet.max_column

3

请注意,该max_column方法返回一个整数而不是Excel中显示的字母。

从表格中获取行和列

您可以分割Worksheet对象以获取Cell电子表格的行,列或矩形区域中的所有对象。然后,您可以遍历切片中的所有单元格。在交互式shell中输入以下内容:

>>> import openpyxl

>>> wb = openpyxl.load_workbook('test.xlsx')

>>> sheet = wb.get_sheet_by_name('Sheet1')

>>> tuple(sheet['A1':'C3'])

((, , ), (,

, ), (, ,

))

>>> for rowOfCellObjects in sheet['A1':'C3']:

for cellObj in rowOfCellObjects:

print(cellObj.coordinate, cellObj.value)

print('--- END OF ROW ---')

A1 2015-04-05 13:34:02

B1 Apples

C1 73

--- END OF ROW ---

A2 2015-04-05 03:41:23

B2 Cherries

C2 85

--- END OF ROW ---

A3 2015-04-06 12:46:51

B3 Pears

C3 14

--- END OF ROW ---

在这里,我们截取从A1到C3这一区域的cell。为了帮助我们测试截取的区域是否如设计一样,我们可以使用tuple()函数来展示其中的Cell对象。

要打印区域中每个单元格的值,我们使用两个for循环。中代码用于遍历行。然后,对于每一行,嵌套for循环遍历该行中的每个列。

要访问特定行或列中单元格的值,还可以使用Worksheet对象rows和columns属性。在交互式shell中输入以下内容:

>>> import openpyxl

>>> wb = openpyxl.load_workbook('test.xlsx')

>>> sheet = wb.active

>>> sheet.columns[1]

(, , , ,

, , )

>>> for cellObj in sheet.columns[1]:

print(cellObj.value)

Apples

Cherries

Pears

Oranges

Apples

Bananas

Strawberries

使用对象Worksheet上的rows属性将为您提供元组数组。这些内部元组中的每一个对象都代表一行,并包含该行中的Cell对象。columns属性还为您提供元组数组,每个内部元组包含Cell特定对象列。例如.xlsx,因为有7行和3列,rows给我们一个7元组的数组(每个包含3个Cell对象),columns给我们一个3元组的数组(每个元组包含7个Cell对象)。

要访问一个特定的元组,您可以通过更大元组中的索引来引用它。例如,要获取表示列B的元组,请使用sheet.columns[1]。要获取包含CellA列中对象的元组,您可以使用sheet.columns[0]。一旦你有一个表示一行或一列的元组,你就可以遍历它的Cell对象并打印它们的值。

编写Excel文档

OpenPyXL还提供了编写数据的方法,这意味着您的程序可以创建和编辑电子表格文件。使用Python,创建包含数千行数据的电子表格非常简单。

创建和保存Excel文档

调用openpyxl.Workbook()函数以创建一个新的空白Workbook对象。在交互式shell中输入以下内容:

>>> import openpyxl

>>> wb = openpyxl.Workbook()

>>> wb.get_sheet_names()

['Sheet']

>>> sheet = wb.active

>>> sheet.title

'Sheet'

>>> sheet.title = 'Spam Bacon Eggs Sheet'

>>> wb.get_sheet_names()

['Spam Bacon Eggs Sheet']

工作簿将从名为Sheet的单个工作表开始。您可以通过在其title属性中存储新字符串来更改工作表的名称。

每次修改Workbook对象或其工作表和单元格时,在调用save()工作簿方法之前,不会保存电子表格文件。在交互式shell中输入以下内容(当前工作目录中包含test.xlsx):

>>> import openpyxl

>>> wb = openpyxl.load_workbook('test.xlsx')

>>> sheet = wb.active

>>> sheet.title ='垃圾邮件垃圾邮件'

>>> wb.save('test_copy. XLSX')

在这里,我们更改工作表的名称。为了保存我们的更改,我们将文件名作为字符串传递给save()方法。传递与原始文件名不同的文件名,例如'test_copy.xlsx',将更改保存到电子表格的副本。

无论何时编辑从文件加载的电子表格,都应始终将新编辑的电子表格保存为与原始文件不同的文件名。这样,如果代码中的错误导致新的,已保存的文件包含不正确或损坏的数据,您仍然可以使用原始电子表格文件。

创建和删除表格

可以使用create_sheet()和remove_sheet()方法在工作簿中添加和删除工作表。在交互式shell中输入以下内容:

>>> import openpyxl

>>> wb = openpyxl.Workbook()

>>> wb.get_sheet_names()

['Sheet']

>>> wb.create_sheet()

>>> wb.get_sheet_names()

['Sheet', 'Sheet1']

>>> wb.create_sheet(index=0, title='First Sheet')

>>> wb.get_sheet_names()

['First Sheet', 'Sheet', 'Sheet1']

>>> wb.create_sheet(index=2, title='Middle Sheet')

>>> wb.get_sheet_names()

['First Sheet', 'Sheet', 'Middle Sheet', 'Sheet1']

该create_sheet()方法返回一个Worksheet名为的新对象SheetX,默认情况下,该对象设置为工作簿中的最后一个工作表。(可选)可以使用index和title关键字参数指定新工作表的索引和名称。

输入以下内容继续上一个示例:

>>> wb.get_sheet_names()

['First Sheet','Sheet','Middle Sheet','Sheet1']

>>> wb.remove_sheet(wb.get_sheet_by_name('Middle Sheet'))

>>> wb.remove_sheet(wb.get_sheet_by_name('Sheet1'))

>>> wb.get_sheet_names()

['First Sheet','Sheet' ]

该remove_sheet()方法将Worksheet对象而不是工作表名称的字符串作为其参数。如果您只知道要删除的工作表的名称,请调用get_sheet_by_name()并将其返回值传递给remove_sheet()。

save()在将工作表添加到工作簿或从工作簿中删除工作表之后,请记住调用该方法来保存更改。

将值写入单元格

将值写入单元格就像将值写入字典中的键一样。在交互式shell中输入:

>>> import openpyxl

>>> wb = openpyxl.Workbook()

>>> sheet = wb.get_sheet_by_name('Sheet')

>>> sheet['A1'] = 'Hello world!'

>>> sheet['A1'].value

'Hello world!'

如果将单元格的坐标作为字符串,则可以像Worksheet对象上的字典键一样使用它来指定要写入的单元格。

类似程序的想法

由于许多办公室工作人员一直使用Excel电子表格,因此可以自动编辑和编写Excel文件的程序非常有用。这样的程序可以执行以下操作:

从一个电子表格中读取数据并将其写入其他电子表格的部分内容。从网站,文本文件或剪贴板中读取数据并将其写入电子表格。自动“清理”电子表格中的数据。例如,它可以使用正则表达式来读取多种格式的电话号码,并将它们编辑为单一的标准格式。

设置单元格的字体样式

样式化某些单元格,行或列可以帮助您强调电子表格中的重要区域。例如,在产品电子表格中,您的程序可以将粗体文本应用于马铃薯,大蒜等。或者,您可能希望以每斤超过5元的成本对每一行进行斜体显示。手动设置大型电子表格的部分内容会很繁琐,但您的程序可以马上执行。

要自定义单元格中的字体样式,请务必从openpyxl.styles模块中导入Font()函数。

from openpyxl.styles import Font

这是一个创建新工作簿并将单元格A1设置为具有24磅斜体字体的示例。在交互式shell中输入以下内容:

>>> import openpyxl

>>> from openpyxl.styles import Font

>>> wb = openpyxl.Workbook()

>>> sheet = wb.get_sheet_by_name('Sheet')

>>> italic24Font = Font(size=24, italic=True)

>>> sheet['A1'].font = italic24Font

>>> sheet['A1'] = 'Hello world!'

>>> wb.save('styled.xlsx')

可以通过将Font对象分配给style属性来设置单元格的样式。

在此示例中,Font(size=24, italic=True)返回Font存储在italic24Font中的对象。关键字参数Font(),size和italic,配置Font对象的属性。当fontObj分配给单元格的font属性时,所有字体样式信息都应用于单元格A1。

字体对象

要设置字体样式属性,请将关键字参数传递给Font()。表12-2显示了该Font()函数的可能关键字参数。

表12-2。字体style属性的关键字参数

关键字 参数 数据类型 描述

name 字符串 字体名称,例如'Calibri'或'Times New Roman'

size 整数 字体大小

bold 布尔 True,粗体字体

italic 布尔 True,斜体字体

您可以调用Font()以创建Font对象并将该Font对象存储在变量中。然后传递给它Style(),将结果Style对象存储在变量中,并将该变量赋值给Cell对象的style属性。例如,此代码创建各种字体样式:

>>> import openpyxl

>>> from openpyxl.styles import Font

>>> wb = openpyxl.Workbook()

>>> sheet = wb.get_sheet_by_name('Sheet')

>>> fontObj1 = Font(name='Times New Roman', bold=True)

>>> sheet['A1'].font = fontObj1

>>> sheet['A1'] = 'Bold Times New Roman'

>>> fontObj2 = Font(size=24, italic=True)

>>> sheet['B3'].font = fontObj2

>>> sheet['B3'] = '24 pt Italic'

>>> wb.save('styles.xlsx')

在这里,我们存储一个Font对象fontObj1,然后将A1 Cell对象的font属性设置为fontObj1。我们用另一个Font对象重复该过程来设置第二个单元格的样式。运行此代码后,电子表格中A1和B3单元格的样式将设置为自定义字体样式。

对于单元格A1,我们将字体名称'Times New Roman'设置bold为并设置为true,因此我们的文本以粗体Times New Roman显示。我们没有指定大小,因此使用openpyxl默认值11。在单元格B3中,我们的文本是斜体,大小为24; 我们没有指定字体名称,因此使用了openpyxl默认的Calibri。

公式

以等号开头的公式可以将单元格配置为包含从其他单元格计算的值。在本节中,您将使用该openpyxl模块以编程方式将公式添加到单元格,就像任何正常值一样。例如:

>>> sheet ['B9'] ='= SUM(B1:B8)'

这将存储= SUM(B1:B8)作为单元格B9中的值。这将B9单元格设置为计算单元格B1到B8中的值之和的公式。您可以在图12-5中看到这一点。

图12-5。单元格B9包含公式= SUM(B1:B8),其添加单元格B1至B8。

公式的设置与单元格中的任何其他文本值一样。在交互式shell中输入以下内容:

>>> import openpyxl

>>> wb = openpyxl.Workbook()

>>> sheet = wb.active

>>> sheet ['A1'] = 200

>>> sheet ['A2'] = 300

>>> sheet [ 'A3'] ='= SUM(A1:A2)'

>>> wb.save('writeFormula.xlsx')

A1和A2中的单元分别设置为200和300。单元格A3中的值设置为一个公式,该公式将A1和A2中的值相加。在Excel中打开电子表格时,A3将显示其值为500。

Excel公式为电子表格提供了一定程度的可编程性,但对于复杂的任务可能很快变得无法管理。相反Python代码更具可读性。

调整行和列

在Excel中,调整行和列的大小就像单击和拖动行或列标题的边缘一样简单。但是,如果您需要根据单元格的内容设置行或列的大小,或者如果要在大量电子表格文件中设置大小,则编写Python程序要快得多。

行和列也可以完全隐藏在视图之外。或者它们可以“冻结”到位,以便它们始终在屏幕上可见,并在打印电子表格时显示在每个页面上(这对标题很方便)。

设置行高和列宽

Worksheet对象具有控制行高和列宽的属性row_dimensions和column_dimensions属性。在交互式shell中输入:

>>> import openpyxl

>>> wb = openpyxl.Workbook()

>>> sheet = wb.active

>>> sheet['A1'] = 'Tall row'

>>> sheet['B2'] = 'Wide column'

>>> sheet.row_dimensions[1].height = 70

>>> sheet.column_dimensions['B'].width = 20

>>> wb.save('dimensions.xlsx')

工作表row_dimensions和column_dimensions拥有类似字典的值; row_dimensions包含RowDimension对象,column_dimensions包含ColumnDimension对象。在row_dimensions,您可以使用行号(在本例中为1或2)访问其中一个对象。在column_dimensions,您可以使用列的字母(在本例中为A或B)访问其中一个对象。

获得RowDimension对象后,可以设置其高度。获得ColumnDimension对象后,可以设置其宽度。行高可以设置为0和409之间的整数或浮点值。此值表示以点为单位测量的高度,其中一个点等于1/72英寸。默认行高为12.75。列宽可以设置为0和255之间的整数或浮点值。此值表示可以在单元格中显示的默认字体大小(11磅)的字符数。默认列宽为8.43个字符。宽度为0的列或高度为0的行对用户是隐藏的。

合并和取消合并cell

可以使用merge_cells()薄片方法将矩形区域的单元合并到单个单元中。在交互式shell中输入以下内容:

>>> import openpyxl

>>> wb = openpyxl.Workbook()

>>> sheet = wb.active

>>> sheet.merge_cells('A1:D3')

>>> sheet['A1'] = 'Twelve cells merged together.'

>>> sheet.merge_cells('C5:D5')

>>> sheet['C5'] = 'Two merged cells.'

>>> wb.save('merged.xlsx')

参数merge_cells()是要合并的矩形区域的左上角和右下角单元格的单个字符串:'A1:D3'将12个单元格合并为单个单元格。要设置这些合并单元格的值,只需设置合并组的左上角单元格的值即可。

运行此代码时,merged.xlsx将如图12-7所要取消合并单元格,请调用unmerge_cells()sheet方法。将其输入交互式shell。

>>> import openpyxl

>>> wb = openpyxl.load_workbook('merged.xlsx')

>>> sheet = wb.active

>>> sheet.unmerge_cells('A1:D3')

>>> sheet.unmerge_cells('C5:D5')

>>> wb.save('merged.xlsx')

如果您保存更改,然后查看电子表格,您将看到合并的单元格已经变回单个单元格。

冻结窗格

对于太大而无法一次显示的电子表格,“冻结”屏幕上的一些顶行或最左列是有帮助的。例如,冻结的列或行标题即使在滚动电子表格时也始终对用户可见。这些被称为冷冻窗格。在OpenPyXL中,每个Worksheet对象都有一个freeze_panes属性,可以设置为Cell对象或单元格坐标的字符串。请注意,此单元格左侧的所有行和所有列都将被冻结,但单元格本身的行和列不会被冻结。要解冻所有窗格,请设置freeze_panes为None或'A1'。

在交互式shell中输入以下内容:

>>> import openpyxl

>>> wb = openpyxl.load_workbook('produceSales.xlsx')

>>> sheet = wb.active

>>> sheet.freeze_panes ='A2'

>>> wb.save('freezeTest.xlsx' )

如果将freeze_panes属性设置为'A2',则无论用户在电子表格中滚动的位置如何,第1行始终都是可见的。

图12-8。随着freeze_panes设置为'A2',第1行是即使用户向下滚动始终可见。

图表

OpenPyXL支持使用工作表单元格中的数据创建条形图,折线图,散点图和饼图。要制作图表,您需要执行以下操作:

1. Reference从矩形选择的单元格创建对象。

2. Series通过传入对象来创建Reference对象。

3. 创建一个Chart对象。

4. 将Series对象附加到Chart对象。

5. 将Chart对象添加到Worksheet对象,可选择指定图表左上角应定位的单元格。

该Reference对象需要一些解释。Reference通过调用openpyxl.chart.Reference()函数并传递三个参数来创建对象:

1. Worksheet包含图表数据的对象。

2. 一个由两个整数组成的元组,表示包含图表数据的矩形单元格选择的左上角单元格:元组中的第一个整数是行,第二个是列。请注意,1是第一行,而不是0。

3. 一个由两个整数组成的元组,表示包含图表数据的矩形单元格选择的右下角单元格:元组中的第一个整数是行,第二个是列。

输入此交互式shell示例以创建条形图并将其添加到电子表格:

>>> import openpyxl

>>> wb = openpyxl.Workbook()

>>> sheet = wb.active

>>> for i in range(1, 11): # create some data in column A

sheet['A' + str(i)] = i

>>> refObj = openpyxl.chart.Reference(sheet, min_col=1, min_row=1, max_col=1, max_row=10)

>>> seriesObj = openpyxl.chart.Series(refObj, title='First series')

>>> chartObj = openpyxl.chart.BarChart()

>>> chartObj.title = 'My Chart'

>>> chartObj.append(seriesObj)

>>> sheet.add_chart(chartObj, 'C5')

>>> wb.save('sampleChart.xlsx')

这将生成一个如图12-10所示的电子表格。

图12-10。添加了图表的电子表格

我们通过调用创建了一个条形图openpyxl.chart.BarChart()。您也可以通过调用openpyxl.chart.LineChart(),openpyxl.chart.ScatterChart()和openpyxl.chart.PieChart()创建折线图,散点图和饼图。

总结

处理信息的难点往往不是处理本身,而是简单地为您的程序获取正确格式的数据。但是,一旦将电子表格加载到Python中,就可以比手动更快地提取和操作其数据。

您还可以生成电子表格作为程序的输出。因此,如果同事需要将您的文本文件或数千个销售联系人的PDF转移到电子表格文件中,您就不必将其全部复制并粘贴到Excel中。

配备openpyxl模块和一些编程知识,你会发现处理即使是最大的电子表格也是小菜一碟。

发布了47 篇原创文章 · 获赞 96 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/qq_41371349/article/details/104225498