openpyxl 官方教程

安装

使用 pip 安装 openpyxl。建议在不包含系统包的 Python 虚拟环境中安装:

$ pip install openpyxl
$ pip install pillow

也可以访问 Pillow 包页面,选择最新版本,并在页面底部寻找 Windows 二进制包。

使用检出的版本

有时可能需要使用从版本库检出的特定版本,例如某个问题已经修复,但尚未发布新版本:

$ pip install -e hg+https://foss.heptapod.net/openpyxl/openpyxl/@3.1#egg=openpyxl

创建工作簿

开始使用 openpyxl 时,不必先在文件系统中创建文件。只需导入 Workbook 类:

>>> from openpyxl import Workbook
>>> wb = Workbook()

创建工作簿时,总会至少创建一个工作表。可以通过 Workbook.active 属性获取它:

>>> ws = wb.active

使用 Workbook.create_sheet() 方法创建新的工作表:

>>> ws1 = wb.create_sheet("Mysheet") # insert at the end (default)
# or
>>> ws2 = wb.create_sheet("Mysheet", 0) # insert at first position
# or
>>> ws3 = wb.create_sheet("Mysheet", -1) # insert at the penultimate position

创建时会自动命名工作表,依次为 Sheet、Sheet1、Sheet2 等。可随时用 Worksheet.title 属性更改名称:

ws.title = "New Title"

命名后,可以像访问工作簿的键一样获取工作表:

>>> ws3 = wb["New Title"]

通过 Workbook.sheetnames 属性查看工作簿中全部工作表的名称:

>>> print(wb.sheetnames)
['Sheet2', 'New Title', 'Sheet1']

也可以遍历工作表:

>>> for sheet in wb:
...     print(sheet.title)

在同一工作簿内,用 Workbook.copy_worksheet() 方法复制工作表:

>>> source = wb.active
>>> target = wb.copy_worksheet(source)

操作数据

访问单个单元格

知道如何获取工作表后,就可以修改单元格内容。可直接通过工作表的键访问单元格:

>>> c = ws['A4']

这会返回 A4 单元格;如果尚不存在,则创建它。也可以直接赋值:

>>> ws['A4'] = 4

Worksheet.cell() 方法可通过行号和列号访问单元格:

>>> d = ws.cell(row=4, column=2, value=10)

注意:因此,遍历单元格而不是直接访问所需单元格,会把所有被访问的单元格都创建到内存中,即使没有给它们赋值。例如:

>>> for x in range(1,101):
...        for y in range(1,101):
...            ws.cell(row=x, column=y)

这会在内存中创建 100×100 个单元格,却没有实际用途。

访问多个单元格

可以使用切片访问单元格范围:

>>> cell_range = ws['A1':'C2']

也能以类似方式获取行或列的范围:

>>> colC = ws['C']
>>> col_range = ws['C:D']
>>> row10 = ws[10]
>>> row_range = ws[5:10]

还可以使用 Worksheet.iter_rows() 方法:

>>> for row in ws.iter_rows(min_row=1, max_col=3, max_row=2):
...    for cell in row:
...        print(cell)
<Cell Sheet1.A1>
<Cell Sheet1.B1>
<Cell Sheet1.C1>
<Cell Sheet1.A2>
<Cell Sheet1.B2>
<Cell Sheet1.C2>

相应地,Worksheet.iter_cols() 方法会按列返回单元格:

>>> for col in ws.iter_cols(min_row=1, max_col=3, max_row=2):
...     for cell in col:
...         print(cell)
<Cell Sheet1.A1>
<Cell Sheet1.A2>
<Cell Sheet1.B1>
<Cell Sheet1.B2>
<Cell Sheet1.C1>
<Cell Sheet1.C2>

如果需要遍历文件的所有行或列,可以使用 Worksheet.rows 属性:

>>> ws = wb.active
>>> ws['C9'] = 'hello world'
>>> tuple(ws.rows)
((<Cell Sheet.A1>, <Cell Sheet.B1>, <Cell Sheet.C1>),
(<Cell Sheet.A2>, <Cell Sheet.B2>, <Cell Sheet.C2>),
(<Cell Sheet.A3>, <Cell Sheet.B3>, <Cell Sheet.C3>),
(<Cell Sheet.A4>, <Cell Sheet.B4>, <Cell Sheet.C4>),
(<Cell Sheet.A5>, <Cell Sheet.B5>, <Cell Sheet.C5>),
(<Cell Sheet.A6>, <Cell Sheet.B6>, <Cell Sheet.C6>),
(<Cell Sheet.A7>, <Cell Sheet.B7>, <Cell Sheet.C7>),
(<Cell Sheet.A8>, <Cell Sheet.B8>, <Cell Sheet.C8>),
(<Cell Sheet.A9>, <Cell Sheet.B9>, <Cell Sheet.C9>))

或者使用 Worksheet.columns 属性:

>>> tuple(ws.columns)
((<Cell Sheet.A1>,
<Cell Sheet.A2>,
<Cell Sheet.A3>,
<Cell Sheet.A4>,
<Cell Sheet.A5>,
<Cell Sheet.A6>,
...
<Cell Sheet.B7>,
<Cell Sheet.B8>,
<Cell Sheet.B9>),
(<Cell Sheet.C1>,
<Cell Sheet.C2>,
<Cell Sheet.C3>,
<Cell Sheet.C4>,
<Cell Sheet.C5>,
<Cell Sheet.C6>,
<Cell Sheet.C7>,
<Cell Sheet.C8>,
<Cell Sheet.C9>))

只获取值

只需要工作表中的值时,可使用 Worksheet.values 属性。它会遍历所有行,但只返回单元格值:

for row in ws.values:
   for value in row:
     print(value)

Worksheet.iter_rows() 和 Worksheet.iter_cols() 都接受 values_only 参数,使它们仅返回单元格的值:

>>> for row in ws.iter_rows(min_row=1, max_col=3, max_row=2, values_only=True):
...   print(row)

(None, None, None)
(None, None, None)

存储数据

获取 Cell 后,就可以给它赋值:

>>> c.value = 'hello, world'
>>> print(c.value)
'hello, world'

>>> d.value = 3.14
>>> print(d.value)
3.14

保存到文件

保存工作簿最简单、安全的方法,是调用 Workbook 对象的 Workbook.save() 方法:

>>> wb = Workbook()
>>> wb.save('balances.xlsx')

文件扩展名并非必须为 xlsx 或 xlsm;但不使用正式扩展名时,其他应用可能无法直接打开文件。OOXML 文件本质上是 ZIP 文件,因此也可用常用的 ZIP 压缩文件管理器打开。

如有需要,可以设置 wb.template=True,将工作簿保存为模板:

>>> wb = load_workbook('document.xlsx')
>>> wb.template = True
>>> wb.save('document_template.xltx')

保存为流

在 Pyramid、Flask、Django 等 Web 应用中,如果需要把文件保存为流,直接提供一个 NamedTemporaryFile() 即可:

>>> from tempfile import NamedTemporaryFile
>>> from openpyxl import Workbook
>>> wb = Workbook()
>>> with NamedTemporaryFile() as tmp:
        wb.save(tmp.name)
        tmp.seek(0)
        stream = tmp.read()

以下操作会失败:

>>> wb = load_workbook('document.xlsx')
>>> # Need to save with the extension *.xlsx
>>> wb.save('new_document.xlsm')
>>> # MS Excel can't open the document
>>>
>>> # or
>>>
>>> # Need specify attribute keep_vba=True
>>> wb = load_workbook('document.xlsm')
>>> wb.save('new_document.xlsm')
>>> # MS Excel will not open the document
>>>
>>> # or
>>>
>>> wb = load_workbook('document.xltm', keep_vba=True)
>>> # If we need a template document, then we must specify extension as *.xltm.
>>> wb.save('new_document.xlsm')
>>> # MS Excel will not open the document

从文件加载

使用 openpyxl.load_workbook() 打开已有工作簿:

>>> from openpyxl import load_workbook
>>> wb = load_workbook(filename = 'empty_book.xlsx')
>>> sheet_ranges = wb['range names']
>>> print(sheet_ranges['D18'].value)
3

load_workbook 支持以下选项:

  • data_only 决定包含公式的单元格返回公式本身(默认行为),还是 Excel 上次读取工作表时保存的值。
  • keep_vba 决定是否保留 Visual Basic 元素,默认不保留。即使保留,也无法编辑这些元素。
  • 只读模式使用更少内存且速度更快,但不提供所有功能,例如图表、图片等;对应参数为 read_only。
  • rich_text 决定是否保留单元格中的富文本格式,默认值为 False。
  • keep_links 决定是否保留来自外部工作簿的缓存数据。

加载工作簿时出错

openpyxl 有时无法打开工作簿,通常是文件本身存在问题。在这种情况下,openpyxl 会尝试提供更多信息。它严格遵循 OOXML 规范,并会拒绝不符合规范的无效文件。遇到这种情况时,可以将 openpyxl 的异常信息反馈给生成该文件的应用或库的开发者。OOXML 规范公开可用,开发者应遵循它。

搜索 ECMA-376 可以找到规范;多数实现细节位于第 4 部分。

本教程到此结束,接下来可以阅读 简单用法。

来源与许可

原文:openpyxl 3.1.3 官方文档,Eric Gazoni、Charlie Clark 及 openpyxl 贡献者。文档首页声明 MIT/Expat 许可;本文为中文翻译,源示例代码保留。原文中的 Workbook.sheetname 笔误已按示例与 API 改为 Workbook.sheetnames。

官方原文 · 许可证与版权声明

原文参考链接

许可证原文

MIT License

Copyright 2010 – 2024, See AUTHORS.
openpyxl authors: Eric Gazoni, Charlie Clark and contributors.
Copyright line retained from the documentation footer; MIT/Expat license confirmed on the documentation home page.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容