Skip to content

Latest commit

 

History

History
933 lines (610 loc) · 33.3 KB

06.md

File metadata and controls

933 lines (610 loc) · 33.3 KB

六、电子表格的乐趣

在本章中,我们将介绍以下配方:

  • 编写 CSV 电子表格
  • 更新 CSV 电子表格
  • 阅读 Excel 电子表格
  • 更新 Excel 电子表格
  • 在 Excel 电子表格中创建新工作表
  • 在 Excel 中创建图表
  • 在 Excel 中使用格式
  • 图书馆的阅读与写作
  • 在 LibreOffice 中创建宏

介绍

电子表格是计算机世界中最通用、最无所不在的工具之一。几乎所有使用计算机作为日常操作一部分的人都使用他们对纸张和单元格的直观方法。甚至有一个笑话说,整个复杂的业务都是在一个电子表格中管理和描述的,它们是一个非常强大的工具。

这使得自动读取和写入电子表格的能力非常强大。我们将在本章中了解如何处理电子表格,主要是最常见的格式 Excel。最后一个方法将包括一个免费的替代方案 Libre-Office,特别是如何在其中使用 Python 作为脚本语言。

编写 CSV 电子表格

CSV 文件是易于共享的简单电子表格。它们基本上是一个包含表格数据的文本文件,以简单的表格格式用逗号分隔(因此命名为逗号分隔值)。CSV 文件可以使用 Python 的标准库创建,并且可以被大多数电子表格软件读取。

准备

对于这个配方,只需要标准的 Python 库。一切都准备好了!

怎么做。。。

  1. 导入csv模块:
>>> import csv
  1. 使用数据的排序方式和要存储的数据定义标题:
>>> HEADER = ('Admissions', 'Name', 'Year')
>>> DATA = [
... (225.7, 'Gone With the Wind', 1939),
... (194.4, 'Star Wars', 1977),
... (161.0, 'ET: The Extra-Terrestrial', 1982)
... ]
  1. 将数据写入 CSV 文件:
>>> with open('movies.csv', 'w',  newline='') as csvfile:
...     movies = csv.writer(csvfile)
...     movies.writerow(HEADER)
...     for row in DATA:
...         movies.writerow(row)
  1. 在电子表格中检查生成的 CSV 文件。在以下屏幕截图中,将使用 LibreOffice 软件显示该文件:

它是如何工作的。。。

在*如何做…*部分中步骤 1 和 2 的准备工作完成后,步骤 3 是完成该工作的部分。

它以写入(w模式打开一个新文件movies.csv。然后,csvfile中的原始文件对象创建一个 writer。所有这些都发生在一个with块中,因此它会在结束时关闭文件。

Note the newline='' parameter. This is done to make the writer store the newline directly and avoid incompatibility issues.

编写器使用.writerow逐行写入元素。第一个是HEADER,然后是每行数据。

还有更多。。。

显示的代码以默认方言存储数据。方言定义了每行数据的分隔方式(逗号或其他字符)、转义方式、换行符等。如果需要调整方言,可以在writer调用中定义这些参数。有关可定义的所有参数的列表,请参见以下链接:

https://docs.python.org/3/library/csv.html#dialects-和格式化参数

CSV files are better when simple. If the data to be stored is complicated, maybe the best alternative is not a CSV file. But CSV files are extremely useful when dealing with tabular data. They can be understood by virtually all programs, and even dealing with them at a low level is easy.

完整的csv模块文档可在此处找到:

https://docs.python.org/3/library/csv.html 。

另见

  • 第四章中读取 CSV 文件配方*,搜索读取本地文件*
  • 更新 CSV 文件配方

更新 CSV 文件

鉴于 CSV 文件是简单的文本文件,更新其内容的最佳解决方案是读取它们,将它们更改为内部 Python 对象,然后以相同的格式写入结果。在这个食谱中,我们将看到如何做到这一点。

准备

在这个配方中,我们将使用 GitHub 上的上提供的movies.csv文件 https://github.com/PacktPublishing/Python-Automation-Cookbook/blob/master/Chapter06/movies.csv 。它包含以下数据:

| 入院 | 名称 | 年 | | 225.7 | 飘 | 1939 | | 194.4 | 星球大战 | 1968 | | 161 | 外星人 | 1982 |

注意Star Wars的年份不正确(应该是 1977 年)。我们将在食谱中更改它。

怎么做。。。

  1. 导入csv模块并定义文件名:
>>> import csv
>>> FILENAME = 'movies.csv'
  1. 使用DictReader读取文件内容,并将其转换为有序行列表:
>>> with open(FILENAME, newline='') as file:
...     data = [row for row in csv.DictReader(file)]
  1. 检查获得的数据。将适当的值从 1968 更改为 1977:
>>> data
[OrderedDict([('Admissions', '225.7'), ('Name', 'Gone With the Wind'), ('Year', '1939')]), OrderedDict([('Admissions', '194.4'), ('Name', 'Star Wars'), ('Year', '1968')]), OrderedDict([('Admissions', '161.0'), ('Name', 'ET: The Extra-Terrestrial'), ('Year', '1982')])]
>>> data[1]['Year']
'1968'
>>> data[1]['Year'] = '1977'
  1. 再次打开文件,并存储值:
>>> HEADER = data[0].keys()
>>> with open(FILENAME, 'w', newline='') as file:
...     writer = csv.DictWriter(file, fieldnames=HEADER)
...     writer.writeheader()
...     writer.writerows(data)
  1. 在电子表格软件中检查结果。结果与编写 CSV 电子表格配方的步骤 4 中显示的结果类似。

它是如何工作的。。。

在*如何做…*部分的步骤 2 中导入csv模块后,我们从文件中提取所有数据。该文件在一个with块中打开。DictReader方便地将其转换为一个字典列表,其中键位于标题值上。

然后可以对方便格式化的数据进行操作和更改。我们在步骤 3 中将数据更改为适当的值。

In this recipe, we change the value directly, but searching may be required in a more general case.

步骤 4 覆盖文件,并使用DictWriter存储数据。DictWriter要求我们通过fieldnames来定义列上的字段。为了获得它,我们检索其中一行的密钥并将其存储在HEADER中。

在w模式下再次打开该文件以覆盖它。DictWriter首先用.writeheader存储头文件,然后用对.writerows的一次调用存储所有行。

The rows can also be added one by one by calling .writerow

关闭with块后,文件被存储并可以检查。

还有更多。。。

CSV 文件的方言通常是已知的,但可能不是。在这种情况下,Sniffer类可以提供帮助。它分析文件(或整个文件)的一个样本,并返回一个dialect对象,以允许以正确的方式读取:

>>> with open(FILENAME, newline='') as file:
...    dialect = csv.Sniffer().sniff(file.read())

打开文件时,方言可以传递给DictReader类。文件需要打开两次才能读取。

Remember to use the dialect on the DictWriter class as well to save the file in the same format.

csv模块的完整文档可在此处找到:

https://docs.python.org/3.6/library/csv.html 。

另见

  • 第 4 章中的读取 CSV 文件配方搜索和读取本地文件**
  • 编写 CSV 电子表格配方

阅读 Excel 电子表格

MS Office 可以说是最常见的 Office 套件软件,使其格式几乎成为标准。就电子表格而言,Excel 可能是最常用的一种,也是一种易于交换的格式。

在这个配方中,我们将看到如何使用openpyxl模块从 Python 以编程方式从 Excel 电子表格中获取信息。

准备

我们将使用openpyxl模块。我们应该安装模块,将其添加到我们的requirements.txt文件中,如下所示:

$ echo "openpyxl==2.5.4" >> requirements.txt
$ pip install -r requirements.txt

在 GitHub 存储库中,有一个名为movies.xlsx的 Excel 电子表格,其中包含按出勤率排列的前十部电影的信息。可在此处找到该文件:

https://github.com/PacktPublishing/Python-Automation-Cookbook/blob/master/Chapter06/movies.xlsx 。

信息来源是以下网页:

http://www.mrob.com/pub/film-video/topadj.html 。

怎么做。。。

  1. 导入openpyxl模块:
>>> import openpyxl
  1. 将文件加载到内存中:
>>> xlsfile = openpyxl.load_workbook('movies.xlsx')
  1. 列出所有图纸并获取第一张,这是唯一包含数据的图纸:
>>> xlsfile.sheetnames
['Sheet1']
>>> sheet = xlsfile['Sheet1']
  1. 获取单元格B4和D4的值(E.T.招生和主任):
>>> sheet['B4'].value
161
>>> sheet['D4'].value
'Steven Spielberg'
  1. 获取行和列的大小。任何超出该范围的单元格都将返回None作为值:
>>> sheet.max_row
11
>>> sheet.max_column
4
>>> sheet['A12'].value
>>> sheet['E1'].value

它是如何工作的。。。

在步骤 1 中导入模块后,*如何操作…*部分中的步骤 2 将文件加载到Workbook对象中的内存中。每个工作簿可以包含一个或多个包含单元格的工作表。

为了确定可用的工作表,在步骤 3 中,我们获取所有工作表(本例中只有一个),然后像字典一样访问工作表以检索Worksheet对象。

Worksheet可以通过名称直接访问所有单元格,如A4或C3。它们中的每一个都将返回一个Cell对象。.value属性将值存储在单元格中。

Cell

通过max_columns和max_rows可以获得存储数据的区域。这使我们能够在数据范围内进行搜索。

D1

1D

区域外的单元格可以访问,但不会返回数据。它们可以用来写新的信息。

还有更多。。。

也可以使用sheet.cell(column, row)检索单元格。两个元素都从 1 开始。

从工作表中迭代的数据区域内的所有单元格,例如:

>>> for row in sheet:
...     for cell in row:
...         # Do stuff with cell

这将逐行返回包含所有单元格的列表:A1、A2、A3。。。B1、B2、B3 等。

sheet.columns

检索单元格时,您可以通过.coordinate、.row和.column找到它们的位置:

>>> cell.coordinate
'D4'
>>> cell.column
'D'
>>> cell.row
4

完整的openpyxl文档可在此处找到:

https://openpyxl.readthedocs.io/en/stable/index.html 。

另见

  • 更新 Excel 电子表格配方
  • 在 Excel 电子表格中创建新工作表配方
  • 在 Excel中创建图表的方法
  • 使用 Excel中的格式

更新 Excel 电子表格

在这个配方中,我们将看到如何更新现有的 Excel 电子表格。这将包括更改单元格中的原始值,还包括设置打开电子表格时要计算的公式。我们还将了解如何向单元格添加注释。

准备

我们将使用模块openpyxl。我们应该安装模块,将其添加到我们的requirements.txt文件中,如下所示:

$ echo "openpyxl==2.5.4" >> requirements.txt
$ pip install -r requirements.txt

在 GitHub 存储库中,有一个名为movies.xlsx的 Excel 电子表格,其中包含按出勤率排列的前十部电影的信息。

可在此处找到该文件:

https://github.com/PacktPublishing/Python-Automation-Cookbook/blob/master/Chapter06/movies.xlsx 。

怎么做。。。

  1. 导入模块openpyxl和Comment类:
>>> import openpyxl
>>> from openpyxl.comments import Comment
  1. 将文件加载到内存并获取工作表:
>>> xlsfile = openpyxl.load_workbook('movies.xlsx')
>>> sheet = xlsfile['Sheet1']
  1. 获取单元格D4的值(E.T.总监):
>>> sheet['D4'].value
'Steven Spielberg'
  1. 将值更改为仅Spielberg:
>>> sheet['D4'].value = 'Spielberg'
  1. 向该单元格添加注释:
>>> sheet['D4'].comment = Comment('Changed text automatically', 'User')
  1. 添加一个新元素,获取Admission列中所有值的总和:
>>> sheet['B12'] = '=SUM(B2:B11)'
  1. 将电子表格保存到movies_comment.xlsx文件:
>>> xlsfile.save('movies_comment.xlsx')
  1. 检查生成的文件,该文件包括注释和A12中B栏总计的计算:

它是如何工作的。。。

在*如何做…*部分,第一步导入,第二步读取电子表格,我们在第三步选择要更改的单元格。

在步骤 4 中,通过赋值来更新该值。在单元格中添加注释,用新的Comment覆盖.coment属性。请注意,还需要添加发表评论的用户。

值还可以包括公式的说明。在步骤 6 中,我们向单元格B12添加一个新公式。在步骤 8 中打开文件时,计算并显示该值。

The value of a formula is not calculated in the Python object. This means that the formula could contain errors or display unexpected results through bugs. Be sure to double-check that the formulas are correct.

最后,在步骤 9 中,通过调用文件的.save方法将电子表格保存到磁盘。

可以通过外部访问文件来检查注释和值。

还有更多。。。

您可以将数据存储在多个值中,并将其转换为 Excel 的适当类型。例如,存储datetime将以正确的日期格式存储。float或其他数字格式也是如此。

如果需要推断类型,可以在加载文件时使用guess_type参数启用,例如:

>>> xlsfile = openpyxl.load_workbook('movies.xlsx', guess_types=True)
>>> xlsfile['Sheet1']['A1'].value = '37%'
>>> xlsfile['Sheet1']['A1'].value
0.37
>>> xlsfile['Sheet1']['A1'].value = '2.75'
>>> xlsfile['Sheet1']['A1'].value
2.75

向自动生成的单元格添加注释有助于查看生成的文件,明确注释是如何生成的。

虽然可以添加公式以自动生成 Excel 文件,但调试结果可能很棘手。生成结果时,通常最好使用 Python 进行计算,并将结果存储在 raw 中。

完整的openpyxl文档可在此处找到:

https://openpyxl.readthedocs.io/en/stable/index.html 。

另见

  • 读取 Excel 电子表格配方
  • 在 Excel 电子表格上创建新工作表的方法
  • 在 Excel中创建图表的方法
  • 使用 Excel中的格式

在 Excel 电子表格上创建新工作表

在此配方中,我们将演示如何从头创建新的 Excel 电子表格,以及如何添加和处理多个工作表。

准备

我们将使用模块openpyxl。我们应该安装模块,将其添加到我们的requirements.txt文件中,如下所示:

$ echo "openpyxl==2.5.4" >> requirements.txt
$ pip install -r requirements.txt

我们将在新文件中存储观众最多的电影信息。数据从这里提取:

http://www.mrob.com/pub/film-video/topadj.html 。

怎么做。。。

  1. 导入openpyxl模块:
>>> import openpyxl
  1. 创建一个新的 Excel 文件。它会创建一个名为Sheet的默认工作表:
>>> xlsfile = openpyxl.Workbook()
>>> xlsfile.sheetnames
['Sheet']
>>> sheet = xlsfile['Sheet']
  1. 从源中将有关与会者人数的数据添加到此工作表。为了简单起见,仅添加了前三个:
>>> data = [
...    (225.7, 'Gone With the Wind', 'Victor Fleming'),
...    (194.4, 'Star Wars', 'George Lucas'),
...    (161.0, 'ET: The Extraterrestrial', 'Steven Spielberg'),
... ]
>>> for row, (admissions, name, director) in enumerate(data, 1):
...     sheet['A{}'.format(row)].value = admissions
...     sheet['B{}'.format(row)].value = name
  1. 创建新图纸:
>>> sheet = xlsfile.create_sheet("Directors")
>>> sheet
<Worksheet "Directors">
>>> xlsfile.sheetnames
['Sheet', 'Directors']
  1. 为每部电影添加导演的姓名:
>>> for row, (admissions, name, director) in enumerate(data, 1):
...    sheet['A{}'.format(row)].value = director
...    sheet['B{}'.format(row)].value = name
  1. 将文件另存为movie_sheets.xlsx:
>>> xlsfile.save('movie_sheets.xlsx')
  1. 打开movie_sheets.xlsx文件,检查是否有两张纸,信息是否正确,如下图所示:

它是如何工作的。。。

在*如何做…*部分,在第 1 步导入模块后,我们在第 2 步创建一个新的电子表格。这是一个只包含默认工作表的新电子表格。

要存储的数据在步骤 3 中定义。请注意,它包含将出现在两张纸上的信息(两张纸上都有姓名,第一张纸上有入学申请,第二张纸上有主任姓名)。在此步骤中,将填充第一张纸。

A

B

enumerate

之后,在步骤 4 中使用名称Directors创建新的工作表。.create_sheet返回新的工作表。

Directors表中的信息在步骤 5 中存储,文件在步骤 6 中保存。

还有更多。。。

可以通过.title属性更改现有图纸的名称:

>>> sheet = xlsfile['Sheet']
>>> sheet.title = 'Admissions'
>>> xlsfile.sheetnames
['Admissions', 'Directors']

小心,因为无法使用xlsfile['Sheet']访问该表。那个名字不存在!

可通过.active属性获取活动工作表,即打开文件时显示的工作表,并使用._active_sheet_index进行更改。第一页索引从0开始:

>> xlsfile.active
<Worksheet "Admissions">
>>> xlsfile._active_sheet_index
0
>>> xlsfile._active_sheet_index = 1
>>> xlsfile.active
<Worksheet "Directors">

也可以使用.copy_worksheet复制该表。请注意,某些数据(例如图表)将不会结转。大多数重复信息将是单元格数据:

new_copied_sheet = xlsfile.copy_worksheet(source_sheet)

完整的openpyxl文档可在此处找到:

https://openpyxl.readthedocs.io/en/stable/index.html 。

另见

  • 读取 Excel 电子表格配方
  • 更新 Excel 电子表格并添加注释配方
  • 在 Excel中创建图表的方法
  • 在 Excel中使用格式

在 Excel 中创建图表

电子表格包括许多处理数据的工具,包括以彩色图表显示数据。让我们看看如何以编程方式将图表附加到 Excel 电子表格。

准备

我们将使用模块openpyxl。我们应该安装模块,将其添加到我们的requirements.txt文件中,如下所示:

$ echo "openpyxl==2.5.4" >> requirements.txt
$ pip install -r requirements.txt

我们将在新文件中存储观众最多的电影信息。数据从这里提取:

http://www.mrob.com/pub/film-video/topadj.html 。

怎么做。。。

  1. 导入openpyxl模块并新建 Excel 文件:
>>> import openpyxl
>>> from openpyxl.chart import BarChart, Reference
>>> xlsfile = openpyxl.Workbook()
  1. 从源中添加有关此工作表中与会者人数的数据。为了简单起见,仅添加了前三个:
>>> data = [
...     ('Name', 'Admissions'),
...     ('Gone With the Wind', 225.7),
...     ('Star Wars', 194.4),
...     ('ET: The Extraterrestrial', 161.0),
... ]
>>> sheet = xlsfile['Sheet']
>>> for row in data:
... sheet.append(row)
  1. 创建一个BarChart对象并用基本信息填充:
>>> chart = BarChart()
>>> chart.title = "Admissions per movie"
>>> chart.y_axis.title = 'Millions'
  1. 创建对data的引用,并将data附加到图表中:
>>> data = Reference(sheet, min_row=2, max_row=4, min_col=1, max_col=2)
>>> chart.add_data(data, from_rows=True, titles_from_data=True)
  1. 将图表添加到工作表并保存文件:
>>> sheet.add_chart(chart, "A6")
>>> xlsfile.save('movie_chart.xlsx')
  1. 检查电子表格中的结果图表,如以下屏幕截图所示:

它是如何工作的。。。

在*如何做…*部分,在步骤 1 和 2 准备好数据后,数据在A1:B4范围内准备好。请注意,A1和B1都包含不应在图表中使用的标题。

在第三步中,我们建立了新的图表,包括基本数据,如标题和Y轴的单位。

Millions

Admissions(millions)

步骤 4 通过Reference对象创建一个参考框,从第 2 行第 1 列到第 4 行第 2 列,这是数据所在的区域,不包括标题。数据通过.add_data添加到图表中。from_rows使每一行成为不同的数据系列。titles_from_data将第一列作为系列名称处理。

该图表在步骤 5 中添加到单元格A6并保存到磁盘。

还有更多。。。

可以创建一系列不同的图表,包括条形图、折线图、面积图(填充直线和轴之间区域的折线图)、饼图或散点图(一个值与另一个值相对绘制的 XY 图)。每种图表都有一个等价类,例如PieChart或LineChart。

同时,每一种都可以有不同的类型。例如,BarChart的默认类型为 column,垂直打印条,但也可以垂直打印,选择不同的类型:

>>> chart.type = 'bar'

查看openpyxl文档,查看所有可用的组合。

不需要从数据中提取x轴标签,而是可以使用set_categories显式设置。例如,将步骤 4 与以下代码进行比较:

data = Reference(sheet, min_row=2, max_row=4, min_col=2, max_col=2)
labels = Reference(sheet, min_row=2, max_row=4, min_col=1, max_col=1)
chart.add_data(data, from_rows=False, titles_from_data=False)
chart.set_categories(labels)

也可以使用描述区域的文本标签来输入范围,而不是使用Reference对象:

chart.add_data('Sheet!B2:B4', from_rows=False, titles_from_data=False)
chart.set_categories('Sheet!A2:A4')

如果需要以编程方式创建数据范围,则这种描述方式可能更难处理。

完整的openpyxl文档可在此处找到:

https://openpyxl.readthedocs.io/en/stable/index.html 。

另见

  • 读取 Excel 电子表格配方
  • 更新 Excel 电子表格并添加注释配方
  • 在 Excel 电子表格上创建新工作表的方法
  • 在 Excel中使用格式

在 Excel 中使用格式

在电子表格中显示信息不仅仅是将信息组织到单元格中或以图形方式显示在图表中,还包括更改格式以突出显示信息的要点。在本配方中,我们将了解如何操作单元格格式以增强数据并以最佳方式呈现数据。

准备

我们将使用模块openpyxl。我们应该安装模块,将其添加到我们的requirements.txt文件中,如下所示:

$ echo "openpyxl==2.5.4" >> requirements.txt
$ pip install -r requirements.txt

我们将在新文件中存储观众最多的电影信息。数据从这里提取:

http://www.mrob.com/pub/film-video/topadj.html 。

怎么做。。。

  1. 导入openpyxl模块并新建 Excel 文件:
>>> import openpyxl
>>> from openpyxl.styles import Font, PatternFill, Border, Side
>>> xlsfile = openpyxl.Workbook()
  1. 从源中添加有关此工作表中与会者人数的数据。为简单起见,仅添加前四个:
>>> data = [
...    ('Name', 'Admissions'),
...    ('Gone With the Wind', 225.7),
...    ('Star Wars', 194.4),
...    ('ET: The Extraterrestrial', 161.0),
...    ('The Sound of Music', 156.4),
]
>>> sheet = xlsfile['Sheet']
>>> for row in data:
...    sheet.append(row)
  1. 定义用于设置电子表格样式的颜色:
>>> BLUE = "0033CC"
>>> LIGHT_BLUE = 'E6ECFF'
>>> WHITE = "FFFFFF"
  1. 以蓝色背景和白色字体定义标题:
>>> header_font = Font(name='Tahoma', size=14, color=WHITE)
>>> header_fill = PatternFill("solid", fgColor=BLUE)
>>> for row in sheet['A1:B1']:
...     for cell in row:
...         cell.font = header_font
...         cell.fill = header_fill
  1. 为列定义备用模式,并在标题后的每行上定义边框:
>>> white_side = Side(border_style='thin', color=WHITE)
>>> blue_side = Side(border_style='thin', color=BLUE)
>>> alternate_fill = PatternFill("solid", fgColor=LIGHT_BLUE)
>>> border = Border(bottom=blue_side, left=white_side, right=white_side)
>>> for row_index, row in enumerate(sheet['A2:B5']):
...     for cell in row:
...         cell.border = border
...         if row_index % 2:
...             cell.fill = alternate_fill
  1. 将文件另存为movies_format.xlsx:
>>> xlsfile.save('movies_format.xlsx')
  1. 检查生成的文件:

它是如何工作的。。。

在*如何做…*部分,我们在步骤 1 中导入openpyxl模块并创建一个新的 Excel 文件。在步骤 2 中,我们将数据添加到第一张工作表中。步骤 3 也是定义要使用的颜色的准备步骤。颜色是以十六进制格式定义的,这在网页设计领域很常见。

https://coolors.co/

在步骤 4 中,我们准备好定义标题的格式。标题将有不同的字体(Tahoma),更大的尺寸(14pt),蓝色背景为白色。为此,我们准备了一个具有字体、大小和前景色的Font对象,以及一个具有背景色的PatternFill对象。

创建header_font和header_fill后的循环将字体和填充应用于适当的单元格。

在步骤 5 中,对行和备用背景应用边框。边框的顶部和底部为蓝色,左侧和右侧为白色。填充的创建方式与步骤 4 类似,但为浅蓝色。背景仅应用于偶数行。

文件最终在步骤 6 中保存。

还有更多。。。

要定义字体,还有其他可用选项,如粗体、斜体、删除线或下划线。如果需要更改字体的任何元素,请定义字体并重新指定它。记住检查字体是否可用。

还有多种创建填充的方法。PatternFill接受多种图案,但最有用的是solid。GradientFill也可用于应用双色渐变。

PatternFill

style='solid'

也可以定义条件格式,但最好尝试在 Python 中定义条件,然后应用适当的格式。

可以正确设置数字格式,例如:

cell.style = 'Percent'

这将把值0.37显示为37%。

完整的openpyxl文档可在此处找到:

https://openpyxl.readthedocs.io/en/stable/index.html 。

另见

  • 读取 Excel 电子表格配方
  • 更新 Excel 电子表格并添加注释配方
  • 在 Excel 电子表格上创建新工作表的方法
  • 在 Excel中创建图表的方法

在 LibreOffice 中创建宏

LibreOffice 是一个免费的办公套件,可替代 MS office 和其他办公软件包。它包括一个文本编辑器和一个名为Calc的电子表格程序。Calc 理解常规的 Excel 格式,并且通过其 UNOAPI 完全可以在内部编写脚本。UNO 接口允许对套件进行编程访问,并且可以用不同的语言(如 Java)进行访问。

其中一种可用的语言是 Python,这使得以套件格式生成非常复杂的应用非常容易,因为这样可以使用完整的 Python 标准库。

在本配方中,我们将看到如何将外部 Python 文件添加为宏,以更改电子表格的内容。

准备

需要安装 LibreOffice。可在获取 https://www.libreoffice.org/ 。

下载并安装后,需要将其配置为允许执行宏:

  1. 转到设置|安全性以查找宏安全性详细信息:

  1. 打开宏安全并选择介质以允许执行宏。这将在允许我们运行宏之前显示警告:

要将宏插入文件中,我们将使用名为include_macro.py的脚本,该脚本可在上找到 https://github.com/PacktPublishing/Python-Automation-Cookbook/blob/master/Chapter06/include_macro.py 。带有宏的脚本也可在此处作为libreoffice_script.py使用:

https://github.com/PacktPublishing/Python-Automation-Cookbook/blob/master/Chapter06/libreoffice_script.py 。

将脚本放入的文件名为movies.ods,也可在此处找到:https://github.com/PacktPublishing/Python-Automation-Cookbook/blob/master/Chapter06/movies.ods 。它以.ods格式(LibreOffice 格式)包含一个表,其中列出了 10 部入场人数最多的电影。数据从这里提取:

http://www.mrob.com/pub/film-video/topadj.html 。

怎么做。。。

  1. 使用include_macro.py脚本将libreoffice_script.py附加到文件movies.ods宏文件:
$ python include_macro.py -h
usage: It inserts the macro file "script" into the file "spreadsheet" in .ods format. The resulting file is located in the macro_file directory, that will be created
 [-h] spreadsheet script

positional arguments:
 spreadsheet File to insert the script
 script Script to insert in the file

optional arguments:
 -h, --help show this help message and exit

$ python include_macro.py movies.ods libreoffice_script.py
  1. 在 LibreOffice 中打开生成的文件macro_file/movies.ods。请注意,它显示了一个启用宏的警告(单击启用)。转到工具|宏|运行宏:

  1. 选择movies.ods``libreoffice_script宏下的ObtainAggregated并单击运行。它计算聚集的入院人数并将其存储在单元格B12中。在A15中增加Total标签:

  1. 重复步骤 2 和 3 再次运行。现在它运行所有聚合,但添加了B12并在B13中得到结果:

它是如何工作的。。。

步骤 1 中的主要工作在include_macro.py脚本中完成。它将文件复制到macro_file子目录中,以避免修改输入。

在内部,.ods文件是具有特定结构的 ZIP 文件。该脚本利用 ZIP 文件 Python 模块在内部将脚本添加到适当的子目录中。它还修改了manifest.xml文件,以允许 LibreOffice 知道文件中有一个脚本。

步骤 3 中执行的宏在libreoffice_script.py中定义,包含一个函数:

def ObtainAggregated(*args):
    """Prints the Python version into the current document"""
    # get the doc from the scripting context
    # which is made available to all scripts
    desktop = XSCRIPTCONTEXT.getDesktop()
    model = desktop.getCurrentComponent()
    # get the first sheet
    sheet = model.Sheets.getByIndex(0)

    # Find the admissions column
    MAX_ELEMENT = 20
    for column in range(0, MAX_ELEMENT):
        cell = sheet.getCellByPosition(column, 0)
        if 'Admissions' in cell.String:
            break
    else:
        raise Exception('Admissions not found')

    accumulator = 0.0
    for row in range(1, MAX_ELEMENT):
        cell = sheet.getCellByPosition(column, row)
        value = cell.getValue()
        if value:
            accumulator += cell.getValue()
        else:
            break

    cell = sheet.getCellByPosition(column, row)
    cell.setValue(accumulator)

    cell = sheet.getCellRangeByName("A15")
    cell.String = 'Total'
    return None

变量XSCRIPTCONTEXT自动创建并允许获取当前组件,然后从中获取第一个Sheet。然后,通过.getCellByPosition 迭代工作表以找到Admissions列,并获得具有.String属性的字符串值。使用相同的方法,将列中的所有值聚合,通过.getValue提取它们以获得它们的数值。

B12

也可以通过.getCellRangeByName参照单元格的字符串位置,将Total存储在单元格A15中。

还有更多。。。

Python 解释器嵌入到 LibreOffice 中,这意味着如果 LibreOffice 发生变化,特定版本可能会发生变化。在撰写本书时 LibreOffice 的最新版本(6.0.5)中,包含的版本是 python3.5.1。

UNO 界面非常完整,允许您访问许多高级元素。不幸的是,文档不是很好,实现它可能是复杂和耗时的。文档是用 java 或 C++定义的,在 LyBoice 基本或其他语言中有例子,但是 Python 很少。完整文件可在以下网址找到:https://api.libreoffice.org/ ,参考文献如下:

https://api.libreoffice.org/docs/idl/ref/index.html 。

LibreOffice 是以前一个名为 OpenOffice 的项目的分支。UNO 已经可用,这意味着在搜索涉及 OpenOffice 的 internet 时会找到一些参考资料。

请记住,LibreOffice 能够读取和写入 Excel 文件。某些功能可能不是 100%兼容;例如,可能存在格式问题。

openpyxl

调试有时也很棘手。请记住,在使用新代码重新打开文件之前,请确保文件已完全关闭。

UNO 还能够与 LibreOffice 套件的其他部分协作,例如创建文档。

另见

  • 编写 CSV 电子表格配方
  • 更新 Excel 电子表格并添加注释和公式配方