使用win32com从Python操作Excel


介绍

我想自动处理Excel文件。事实证明,有几种方法可以作为一种语言。
我应该选择哪一个?我将写下最终选择的Python win32com的操作示例。

为什么要通过Python win32com使用Excel

比较Excel VBA,PowerShell COM,Python xlwings,Python openpyxl,Python win32com的结果是,win32com接近了我的需求。

首先,当我想自动操作Excel时,我想到的第一件事是Excel VBA。但是,这似乎有一些不合适的用途。

为了将VBA放在Excel文件的所有者中并对其进行管理,所有用户将被迫使用带有宏的Excel文件,因此有必要考虑从OS到VBA上的Excel版本的详细移动方面。如果您开始考虑强制使用VBA的安全风险,那么这不是一个好选择。

接下来,即使您考虑将充满数据的Excel文件和管理VBA的Excel文件分开,VBA代码管理也很麻烦。管理非文本文件(如Git)并不容易,尽最大努力在里程碑中导出和管理模块似乎很麻烦。如果没有连续维护的费用,我会避免这种选择。

Excel VBA,然后是Excel自动化,提供了PowerShell COM。但是,PowerShell有一个习惯,我不擅长。忘记转义是一个反斜杠,并且对于低级PowerShell编码器来说阈值太高,在这种情况下,转义过程受路径名中通配符字符串的支配。如果大约有100行,我会尽力使用PowerShell。不推荐更多。

接下来,除了其他语言之外,我还担心Python win32com,xlwings,openpyxl。

openpyxl可以读取xlsx,但是我感觉它没有计算公式的计算方法,但是我担心似乎有一种方法可以获取计算结果。我认为我可以读取缓存的数据,但是我担心值可能不一致,或者如果不存在写操作之后不应该读取数据。如果您想读取允许错误的处理或不读取而输出Excel,则Openpyxl似乎易于使用。

xlwings足以使用一个简单的Excel文件。方法列表以dir(workbook)显示,并且方法名称原则上以小写形式统一,这很方便。但是,它似乎并不支持所有Excel功能。例如,如果您想尽可能地释放受保护的Excel工作表,则需要一种变通方法,例如通过xlwings执行VBA代码,该方法适用于数据处理,但给人的印象是无法达到的。此外,假定已经安装了Execel。我尚未确认该操作,但是在某些情况下它正在macOS上运行。

剩下的win32com似乎能够清除所有上述问题。但是,作为限制,假设已经安装了Windows Excel。如果在桌面上运行Excel时通过win32com运行Excel,则该行为可能会更改,并且很容易受到测试环境的影响。在某些情况下,dir(workbook)不显示方法名称的列表,并且如果方法名称的大小写不正确,它将无法按预期运行。由于没有太多的文档,因此在编写Python时,我将参考VBA知识,MS官方API文档,Stackoverflow。

两者都有优点和缺点。 Win32com是详细使用Excel的最佳方法。 Xlwings是对开发人员友好的,可以在将来预期。如果它是一个简短的代码,总共有1个或2个屏幕,则PowerShell可以。我的印象是,如果您自己使用Excel文件,则可以使用不带版本管理的VBA。

前提

  • Windows 10
  • Python3
  • Excel 2013

目录,文件

1
2
3
4
5
. (directory)
|
+ data (directory)
  |
  +-- sample.xlsx

安装套件

1
pip install pywin32

阅读excel

启动或退出Excel

1
2
3
4
5
6
7
import win32com.client

# 起動する
app = win32com.client.Dispatch("Excel.Application")

# 終了する
app.Quit()

从xlsx文件

打开只读工作簿

1
2
3
4
5
6
7
8
from pathlib import Path

# 開く
abspath = str(Path(r"data/sample.xlsx").resolve())
workbook = app.Workbooks.Open(abspath, UpdateLinks=0, ReadOnly=True)

# 閉じる
workbook.Close()

获取工作簿列表

请注意,

xxx[Index]xxx(Index)之间的元素编号开头不同。

1
2
3
print(app.Workbooks.Count)
for i in range(0, app.Workbooks.Count):
    print(app.Workbooks[i].name)
1
2
3
print(app.Workbooks.Count)
for i in range(1, app.Workbooks.Count + 1):
    print(app.Workbooks(i).name)

启用工作簿

1
workbook.Activate()

获取图纸列表

1
2
3
print(workbook.Worksheets.Count)
for i in range(0, workbook.Worksheets.Count):
    print(workbook.Worksheets[i].name)
1
2
3
print(workbook.Worksheets.Count)
for i in range(1, workbook.Worksheets.Count + 1):
    print(workbook.Worksheets(i).name)

从工作表名称

获取工作表

1
sheet = workbook.Worksheets("Sheet1")

从工作表

获取单元格

1
sheet.Cells.Item(1,1).Value

从表

获取范围

1
2
3
4
5
6
7
8
9
10
11
12
arg = "A1:B3"
r = sheet.Range(arg)

ret = list()
for row_index in range(1, r.Rows.Count + 1):
    row = []
    for col_index in range(1, r.Columns.Count + 1):
        row.append(r(row_index, col_index).Address)
    ret.append(row)

print(ret)
   # --> [['$A$1', '$B$1'], ['$A$2', '$B$2'], ['$A$3', '$B$3']]

获取单元格公式

1
2
3
4
5
cell.Formula = '=1+2'
cell.Formula
  # --> '=1+2'
cell.Value
  # --> 3.0

获取单元格值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
row_index, col_index = 1, 2
cell = sheet.Cells(row_index, col_index)
cell.ClearFormats()
cell.NumberFormatLocal
  # --> 'G/標準'

# 整数
cell.Value = 1
cell.Value
  # --> 1.0

# 文字列
cell.Value = 'あ'
cell.Value
  # --> 'あ'

# 日付に解釈されそうな文字列
cell.NumberFormatLocal
  # --> 'G/標準'
cell.Value = '2019-01-01'
cell.NumberFormatLocal
  # --> 'yyyy/m/d'
cell.Value
  # --> pywintypes.datetime(2019, 1, 1, 0, 0, tzinfo=TimeZoneInfo('GMT Standard Time', True))

import datetime
datetime.datetime.fromtimestamp(timestamp=pywindt.timestamp(), tz=pywindt.tzinfo)
  # --> datetime.datetime(2019, 1, 1, 0, 0, tzinfo=TimeZoneInfo('GMT Standard Time', True))

# 時刻に解釈されそうな文字列
cell.Value = '00:00:00'
cell.NumberFormatLocal
  # --> 'h:mm:ss'
cell.Value
  # --> '0.0'
cell.Value = '24:00:00'
cell.Value
  # --> '1.0'
cell.Value = '48:00:00'
cell.Value
  # --> '2.0'

获取单元格文本

1
2
3
4
5
6
7
8
9
cell.ClearFormats()
cell.NumberFormatLocal
  # --> 'G/標準'

cell.Value = '=1'
cell.Value
  # --> 1.0
cell.Text
  # --> '1'

写excel

打开一个新的工作簿

1
workbook = app.Workbooks.Add()

保存工作簿

1
workbook.Save()

其他

使Excel不可见

1
app.Visible = False

设置或删除纸张保护

1
2
sheet.Protect()
sheet.Unprotect()

隐藏警告

1
app.DisplayAlerts = False

获取单元格的地址

1
2
3
4
5
6
7
8
cell.Address
  # --> '$B$1'
cell.GetAddress()
  # --> '$B$1'
cell.GetAddress(RowAbsolute=False, ColumnAbsolute=False)
  # --> 'B1'
# NGな例
#cell.Address(RowAbsolute=False, ColumnAbsolute=False)

提示

dir方法无法使用

1
2
3
4
import win32com.client
app = win32com.client.Dispatch("Excel.Application")
dir(app)
  # --> ['_ApplyTypes_', '_FlagAsMethod', '_LazyAddAttr_', '_NewEnum', '_Release_', '__AttrToID__', '__LazyMap__', '__bool__', '__call__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__int__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_builtMethods_', '_enum_', '_find_dispatch_type_', '_get_good_object_', '_get_good_single_object_', '_lazydata_', '_make_method_', '_mapCachedItems_', '_oleobj_', '_olerepr_', '_print_details_', '_proc_', '_unicode_to_string_', '_username_', '_wrap_dispatch_']

参考资料

库比较

使用Python处理Excel文件的库的比较
https://note.nkmk.me/python-excel-library/

微软

工作簿对象
https://docs.microsoft.com/ja-jp/office/vba/api/excel.workbook

Excel VBA

使用Git管理VBA源
https://qiita.com/ryotaro76/items/63cad3dfb891a9df7c88

PowerShell Excel

希望您对如何将Excel与PowerShell一起使用感兴趣。
https://qiita.com/miyamiya/items/161372111b68bad0744a

python openpyxl

openpyxl-用于读取/写入Excel 2010 xlsx / xlsm文件的Python库
https://openpyxl.readthedocs.io/en/stable/

python win32com

适用于Windows的Python(pywin32)扩展
https://github.com/mhammond/pywin32

TODO:我记得在Exccel win32com上看到一篇井井有条的文章,但是找不到链接。如果找到一个,请写下。

Python xlwings

xlwings-使Excel变得飞起来!
https://docs.xlwings.org/en/stable/index.html

从Excel使用Python
https://qiita.com/katzhide/items/60d0336b322105bf8fe9

使用Python和xlwings玩Excel文件
https://idontwannawork.github.io/posts/edit-excel-with-python-and-xlwings/

如何取消保护工作表?#1032
https://github.com/xlwings/xlwings/issues/1032