编程学习网 > 编程语言 > Python > python openpyxl 教程(python openpyxl 完成excel任务)
2023
05-09

python openpyxl 教程(python openpyxl 完成excel任务)

Excel电子表格是你在某些时候可能不得不处理的东西之一。无论是因为你的老板喜欢它们,还是因为市场需要它们,你可能不得不学习如何与电子表格打交道,这时了解openpyxl就会派上用场!

电子表格是一种非常直观和用户友好的方式,无需任何技术背景就可以操作大型数据集。这就是为什么它们今天仍然被普遍使用。
在这篇文章中,你将学习如何使用openpyxl来:。
充满信心地操纵Excel电子表格
从电子表格中提取信息
创建简单或更复杂的电子表格,包括添加样式、图表等。
本文是为那些对Python数据结构,如dicts和lists有相当了解,同时对OOP和更多中级别的主题感到满意的中级开发者编看的。
1. 在你开始之前
如果你曾经被要求从数据库或日志文件中提取一些数据到Excel电子表格中,或者你经常需要将Excel电子表格转换成一些更可用的编程形式,那么这个教程就非常适合你。让我们跳进openpyxl 快速列车!
实际使用案例
首先,你什么时候需要在现实世界中使用openpyxl这样的包?你将在下面看到几个例子,但实际上,有数百种可能的情况下,这些知识会派上用场。
将新产品导入数据库
你在一家网店公司负责技术工作,你的老板不想花钱买一个很酷很贵的CMS系统。
每次他们想在网上商店添加新产品时,他们就会拿着一个有几百行的Excel电子表格来找你,对于每一行,你都有产品名称、描述、价格等等。
现在,为了导入数据,你必须遍历电子表格的每一行,并将每个产品添加到网上商店中。
将数据库数据导出到电子表格中
假设你有一个数据库表,你记录了所有用户的信息,包括姓名、电话号码、电子邮件地址等等。
现在,营销团队想联系所有的用户,给他们一些折扣优惠或促销。然而,他们没有访问数据库的权限,或者他们不知道如何使用SQL来轻松提取这些信息。
你能做些什么来帮助他们呢?你可以用openpyxl做一个快速的脚本,遍历每一条用户记录,把所有重要的信息放到Excel表格中。
这将为你在公司的下一个生日派对上赢得一块额外的蛋糕!
将信息附加到现有的电子表格上
你可能还需要打开一个电子表格,读取其中的信息,并根据一些业务逻辑,向其中追加更多的数据。
例如,再次使用在线商店的场景,假设你得到一个Excel电子表格的用户列表,你需要在每一行追加他们在你的商店里的消费总额。
这个数据在数据库中,为了做到这一点,你必须读取电子表格,迭代每一行,从数据库中获取消费总额,然后写回电子表格。
对openpyxl来说,这不是一个问题!
学习一些基本的Excel术语
以下是你在使用Excel电子表格时将会看到的基本术语的快速列表。

开始使用openpyxl
现在你已经知道了像 "openpyxl"这样的工具的好处,让我们开始着手安装这个软件包。在本教程中,你应该使用 Python 3.7 和 openpyxl 2.6.2。要安装这个包,你可以做以下工作。
安装软件包后,你应该能够用以下代码创建一个超级简单的电子表格。
from openpyxl import Workbook

workbook = Workbook()
sheet = workbook.active

sheet["A1"] = "hello"
sheet["B1"] = "world!"

workbook.save(filename="hello_world.xlsx")
上面的代码应该在你用来运行代码的文件夹中创建一个名为hello_world.xlsx的文件。如果你用Excel打开该文件,你应该看到类似这样的东西。

Woohoo,你的第一个电子表格创建了!
使用openpyxl读取Excel电子表格
让我们从一个人可以做的最基本的事情开始:阅读电子表格。
你将从阅读电子表格的直接方法到更复杂的例子,在这些例子中,你将阅读数据并将其转换成更有用的Python结构。
本教程的数据集
在你深入学习一些代码实例之前,你应该下载这个样本数据集,并将其存储为sample.xlsx。
这是你将在本教程中使用的数据集之一,它是一个电子表格,其中有来自亚马逊在线产品评论的真实数据样本。这个数据集只是亚马逊提供的一小部分,但对于测试目的来说,它已经足够了。
阅读Excel电子表格的简单方法
最后,让我们开始阅读一些电子表格! 首先,打开我们的样本电子表格。
from openpyxl import load_workbook
workbook = load_workbook(filename="sample.xlsx")
workbook.sheetnames
> ['Sheet 1']

sheet = workbook.active
sheet
<Worksheet "Sheet 1">

sheet.title
>'Sheet 1'

在上面的代码中,你首先使用load_workbook()打开电子表格sample.xlsx,然后你可以使用workbook.sheetnames来查看所有可用于工作的表。之后,workbook.active会选择第一个可用的工作表,在这个例子中,你可以看到它自动选择了表1。使用这些方法是打开电子表格的默认方式,在本教程中你会看到很多次。
现在,在打开电子表格后,你可以像这样轻松地检索其中的数据。
 sheet["A1"] #iloc
<Cell 'Sheet 1'.A1> #loc

 sheet["A1"].value #value 
'marketplace'

 sheet["F10"].value
"G-Shock Men's Grey Sport Watch"

要返回一个单元格的实际值,你需要做.value。否则,你会得到主单元格对象。你也可以使用方法.cell()来检索一个使用索引符号的单元格。记住要添加.value来获取实际值而不是Cell对象。

 sheet.cell(row=10, column=6)
<Cell 'Sheet 1'.F10>

 sheet.cell(row=10, column=6).value
"G-Shock Men's Grey Sport Watch"

你可以看到,无论你决定采用哪种方式,返回的结果都是一样的。然而,在本教程中,你将主要使用第一种方法:["A1"]。
以上向你展示了打开电子表格的最快捷方式。不过,你可以通过附加参数来改变电子表格的加载方式。
额外的读取选项
你可以向load_workbook()传递一些参数,以改变电子表格的加载方式。最重要的是以下两个布尔。
read_only 以只读模式加载电子表格,允许你打开很大的Excel文件。
data_only 忽略加载公式,而只加载结果值。
从电子表格中导入数据
现在你已经学会了关于加载电子表格的基本知识,现在是时候进入有趣的部分了。电子表格中的数值的迭代和实际使用。
在本节中,你将学习到所有不同的数据迭代方式,以及如何将数据转换为可用的东西,更重要的是,如何以Pythonic方式进行转换。
通过数据进行迭代
根据你的需要,有几种不同的方法可以迭代数据。
你可以用列和行的组合对数据进行分割。
 sheet["A1:C2"]
((<Cell 'Sheet 1'.A1>, <Cell 'Sheet 1'.B1>, <Cell 'Sheet 1'.C1>),
 (<Cell 'Sheet 1'.A2>, <Cell 'Sheet 1'.B2>, <Cell 'Sheet 1'.C2>))

You can get ranges of rows or columns:
 # A 列中的所有值
 sheet["A"]
(<Cell 'Sheet 1'.A1>,
 <Cell 'Sheet 1'.A2>,
 
 <Cell 'Sheet 1'.A99>,
 <Cell 'Sheet 1'.A100>)

 # 区域中的所有cell对象
 sheet["A:B"]
((<Cell 'Sheet 1'.A1>,
  <Cell 'Sheet 1'.A2>,
  
  <Cell 'Sheet 1'.A99>,
  <Cell 'Sheet 1'.A100>),
 (<Cell 'Sheet 1'.B1>,
  <Cell 'Sheet 1'.B2>,
  
  <Cell 'Sheet 1'.B99>,
  <Cell 'Sheet 1'.B100>))

 # 5行的所有对象
 sheet[5]
(<Cell 'Sheet 1'.A5>,
 <Cell 'Sheet 1'.B5>,
 
 <Cell 'Sheet 1'.N5>,
 <Cell 'Sheet 1'.O5>)

 # 5和6行所有的数据
 sheet[5:6]
((<Cell 'Sheet 1'.A5>,
  <Cell 'Sheet 1'.B5>,
  
  <Cell 'Sheet 1'.N5>,
  <Cell 'Sheet 1'.O5>),
 (<Cell 'Sheet 1'.A6>,
  <Cell 'Sheet 1'.B6>,
  
  <Cell 'Sheet 1'.N6>,
  <Cell 'Sheet 1'.O6>))

你会注意到,上面所有的例子都返回一个 "元组"。如果你想复习一下如何在Python中处理图元,请查看Python中的列表和图元这篇文章。
也有多种方法使用普通的Python 生成器来浏览数据。你可以使用的主要方法是:
.iter_rows()
.iter_cols()
这两种方法都可以接收以下参数:
min_row
max_row
min_col
max_col
这些参数用于设置迭代的边界:
 for row in sheet.iter_rows(min_row=1,
                            max_row=2,
                            min_col=1,
                            max_col=3):
     print(row)
(<Cell 'Sheet 1'.A1>, <Cell 'Sheet 1'.B1>, <Cell 'Sheet 1'.C1>)
(<Cell 'Sheet 1'.A2>, <Cell 'Sheet 1'.B2>, <Cell 'Sheet 1'.C2>)


 for column in sheet.iter_cols(min_row=1,
                               max_row=2,
                               min_col=1,
                               max_col=3):
     print(column)
(<Cell 'Sheet 1'.A1>, <Cell 'Sheet 1'.A2>)
(<Cell 'Sheet 1'.B1>, <Cell 'Sheet 1'.B2>)
(<Cell 'Sheet 1'.C1>, <Cell 'Sheet 1'.C2>)

你会注意到,在第一个例子中,当使用.iter_rows()遍历行时,你会在每一行得到一个tuple元素。而当使用.iter_cols()并通过列进行迭代时,你会得到一个tuple,而不是列。
你可以传递给这两个方法的一个额外参数是布尔值values_only。当它被设置为True时,将返回单元格的值,而不是Cell对象。
 for value in sheet.iter_rows(min_row=1,
                              max_row=2,
                              min_col=1,
                              max_col=3,
                              values_only=True):
     print(value)
('marketplace', 'customer_id', 'review_id')
('US', 3653882, 'R3O9SGZBVQBV76')

如果你想遍历整个数据集,那么你也可以直接使用属性.rows或.columns,这是使用.iter_rows()和.iter_cols()的快捷方式,不需要任何参数。
 for row in sheet.rows:
     print(row)
(<Cell 'Sheet 1'.A1>, <Cell 'Sheet 1'.B1>, <Cell 'Sheet 1'.C1>

<Cell 'Sheet 1'.M100>, <Cell 'Sheet 1'.N100>, <Cell 'Sheet 1'.O100>)

当你对整个数据集进行迭代时,这些快捷方式非常有用。
使用 Python 的默认数据结构操纵数据
现在你知道了在工作簿中迭代数据的基本原理,让我们看看将数据转换为 Python 结构的聪明方法。
正如你前面看到的,所有迭代的结果都是以 tuple的形式出现的。然而,由于tuple只不过是一个不可变的 list,你可以很容易地访问它的数据并将其转换为其他结构。
例如,你想从sample.xlsx电子表格中提取产品信息,并输入一个字典,其中每个键是一个产品ID。
一个直接的方法是遍历所有的行,挑选你知道的与产品信息相关的列,然后将其存储在一个字典中。让我们把这个代码写出来!
首先,看一下标题,看看你最关心的信息是什么。
 for value in sheet.iter_rows(min_row=1,
                              max_row=1,
                              values_only=True):
     print(value)
('marketplace', 'customer_id', 'review_id', 'product_id', )
这段代码返回电子表格中所有列名的列表。首先,抓取有名字的列。
product_id
product_parent
product_title
product_category
幸运的是,你需要的列都是挨着的,所以你可以使用min_column和max_column来轻松获得你想要的数据。
                            min_col=4,
                              max_col=7,
                              values_only=True):
     print(value)
('B00FALQ1ZC', 937001370, 'Invicta Women's 15150 "Angel" 18k Yellow)
('B00D3RGO20', 484010722, "Kenneth Cole New York Women's KC4944)


很好! 现在你知道如何获得你需要的所有重要的产品信息,让我们把这些数据放到一个字典里。
import json
from openpyxl import load_workbook

workbook = load_workbook(filename="sample.xlsx")
sheet = workbook.active

products = {}

# Using the values_only because you want to return the cells' values
for row in sheet.iter_rows(min_row=2,
                           min_col=4,
                           max_col=7,
                           values_only=True):
    product_id = row[0]
    product = {
        "parent": row[1],
        "title": row[2],
        "category": row[3]
    }
    products[product_id] = product

# Using json here to be able to format the output for displaying later
print(json.dumps(products))
上面的代码返回一个与此类似的JSON。
{
  "B00FALQ1ZC": {
    "parent": 937001370,
    "title": "Invicta Women's 15150 ",
    "category": "Watches"
  },
  "B00D3RGO20": {
    "parent": 484010722,
    "title": "Kenneth Cole New York ",
    "category": "Watches"
  }
}
这里你可以看到,输出只有2个产品,但是如果你按原样运行脚本,那么你应该得到98个产品。
将数据转换为Python类
为了完成本教程的阅读部分,让我们深入研究Python类,看看你如何改进上面的例子,更好地构造数据。
为此,你将使用从Python 3.7开始提供的新的Python 数据类。如果你使用的是旧版本的 Python,那么,你可以使用默认的 Classes 来代替。
所以,首先,让我们看看你所拥有的数据,并决定你想存储什么,以及如何存储它。
正如你在一开始看到的,这个数据来自亚马逊,是一个产品评论的列表。你可以查看亚马逊上的所有列及其含义的列表。
有两个重要的元素你可以从现有的数据中提取。
Products
Reviews
产品有:
ID
Title
Parent
Category
评论还有几个字段:
ID
Customer ID
Stars
Headline
Body
Date
你可以忽略一些字段,使事情变得简单一些。
因此,这两个类的直接实现可以写在一个单独的文件中 classes.py:
import datetime
from dataclasses import dataclass

@dataclass
class Product:
    id: str
    parent: str
    title: str
    category: str

@dataclass
class Review:
    id: str
    customer_id: str
    stars: int
    headline: str
    body: str
    date: datetime.datetime

在定义了数据类之后,你需要将电子表格中的数据转换成这些新的结构。
在进行转换之前,值得再看一下我们的标题,并在列和你需要的字段之间建立一个映射。
for value in sheet.iter_rows(min_row=1,
                              max_row=1,
                              values_only=True):
     print(value)
('marketplace', 'customer_id', 'review_id', 'product_id', )

 # Or an alternative
for cell in sheet[1]:
     print(cell.value)
marketplace
customer_id
review_id
product_id
product_parent
让我们创建一个文件mapping.py,其中有一个所有字段名和它们在电子表格上的列位置(零索引)的列表。
# Product fields
PRODUCT_ID = 3
PRODUCT_PARENT = 4
PRODUCT_TITLE = 5
PRODUCT_CATEGORY = 6

# Review fields
REVIEW_ID = 2
REVIEW_CUSTOMER = 1
REVIEW_STARS = 7
REVIEW_HEADLINE = 12
REVIEW_BODY = 13
REVIEW_DATE = 14
你不一定要做上面的映射。这更多的是为了在解析行数据时的可读性,这样你就不会有很多神奇的数字躺在那里。
最后,让我们看看将电子表格数据解析为产品和评论对象的list所需的代码。
from datetime import datetime
from openpyxl import load_workbook
from classes import Product, Review
from mapping import PRODUCT_ID, PRODUCT_PARENT, PRODUCT_TITLE, 
    PRODUCT_CATEGORY, REVIEW_DATE, REVIEW_ID, REVIEW_CUSTOMER, 
    REVIEW_STARS, REVIEW_HEADLINE, REVIEW_BODY

# 使用只读方法,因为你不打算编辑电子表格
workbook = load_workbook(filename="sample.xlsx", read_only=True)
sheet = workbook.active

products = []
reviews = []

# 使用values_only是因为你只想返回单元格的值
for row in sheet.iter_rows(min_row=2, values_only=True):
    product = Product(id=row[PRODUCT_ID],
                      parent=row[PRODUCT_PARENT],
                      title=row[PRODUCT_TITLE],
                      category=row[PRODUCT_CATEGORY])
    products.append(product)

    # 需要将电子表格中的日期解析为日期时间格式
    spread_date = row[REVIEW_DATE]
    parsed_date = datetime.strptime(spread_date, "%Y-%m-%d")

    review = Review(id=row[REVIEW_ID],
                    customer_id=row[REVIEW_CUSTOMER],
                    stars=row[REVIEW_STARS],
                    headline=row[REVIEW_HEADLINE],
                    body=row[REVIEW_BODY],
                    date=parsed_date)
    reviews.append(review)

print(products[0])
print(reviews[0])

在你运行上面的代码后,你应该得到一些像这样的输出。
Product(id='B00FALQ1ZC', parent=937001370, )
Review(id='R3O9SGZBVQBV76', customer_id=3653882, )
这就是了! 现在你应该有一个非常简单和可消化的类格式的数据,你可以开始考虑将其存储在数据库或任何其他你喜欢的数据存储类型。
使用这种OOP策略来解析电子表格,使以后的数据处理更加简单。
追加新数据
在你开始创建非常复杂的电子表格之前,先看一下如何将数据追加到现有电子表格的例子。
回到你创建的第一个电子表格的例子(hello_world.xlsx),试着打开它并向它追加一些数据,像这样。

from openpyxl import load_workbook

# 首先打开电子表格,选择主工作表
workbook = load_workbook(filename="hello_world.xlsx")
sheet = workbook.active

# 把你想要的东西写进特定的单元格
sheet["C1"] = "writing ;)"

# 保存电子表格
workbook.save(filename="hello_world_append.xlsx")

如果你打开新的hello_world_append.xlsx电子表格,你会看到以下变化。

请注意单元格C1上的附加 "writing ;)

以上就是python openpyxl 教程(python openpyxl 完成excel任务)的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。

扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取