Good news and bad news. I deleted the normal env of installed directories, which usually forces Rhino to recreate it. Updated to 8.17 SRC. In a CPython3 component, both import xlwings
and import pywin32
(with no #r:
s) both raised module not found errors. Then this worked like a charm:
#r: xlwings
import xlwings
print(xlwings)
print(f'{xlwings.__version__=}')
RhinoCodeLogs
Info 02/27/2025 11:44:37 [RhinoCode] Installing "xlwings"
Info 02/27/2025 11:44:37 [RhinoCode] Running process: \.rhinocode\py39-rh8\python.exe -I -m pip --isolated --disable-pip-version-check install --target "\.rhinocode\py39-rh8\site-envs\default-CsO7suzN" --progress-bar off --upgrade --no-warn-script-location --retries 5 --timeout 15 "xlwings"
Info 02/27/2025 11:46:09 [RhinoCode] Running process: \.rhinocode\py39-rh8\python.exe -I -m pip --isolated --disable-pip-version-check list --path "\.rhinocode\py39-rh8\site-envs\default-CsO7suzN" --format freeze
Info 02/27/2025 11:46:12 [RhinoCode] Collecting xlwings
Using cached xlwings-0.33.9-cp39-cp39-win_amd64.whl.metadata (5.8 kB)
Collecting pywin32>=224 (from xlwings)
Using cached pywin32-308-cp39-cp39-win_amd64.whl.metadata (8.3 kB)
Using cached xlwings-0.33.9-cp39-cp39-win_amd64.whl (1.6 MB)
Using cached pywin32-308-cp39-cp39-win_amd64.whl (6.6 MB)
Installing collected packages: pywin32, xlwings
Successfully installed pywin32-308 xlwings-0.33.9
<module 'xlwings' from ' ... \\.rhinocode\\py39-rh8\\site-envs\\default-CsO7suzN\\xlwings\\__init__.py'>
xlwings.__version__='0.33.9'
However this doesn’t work:
#r: xlwings
import xlwings, pywin32
def print_mod_and_ver(module):
print(module)
print(f'{module.__version__=}')
print_mod_and_ver(xlwings)
print_mod_and_ver(pywin32)
xlwings masks pywin32 import errors. Maybe it has other useful features that don’t need it:
__init__.py
# Populate engines list
has_pywin32 = False
if sys.platform.startswith("win"):
try:
from . import _xlwindows
engines.add(Engine(impl=_xlwindows.engine))
has_pywin32 = True
except ImportError:
pass
_xlwings.py
import pywintypes
import win32api
import win32con
It takes a whole bunch of extra setup steps in that too.
After that, adding pywin32 as in your example:
#r: xlwings
#r: pywin32
import xlwings
import win32api
produces:
Traceback (most recent call last):
File "rhinocode:///grasshopper/1/35897f9d-b3b4-43ea-a00f-158e522fc36a/e251201f-92fc-4341-a897-d86b4f7c78af", line 5, in <module>
ModuleNotFoundError: No module named 'win32api'
It could be anything then. But as well as the Import Error mask, xlwings is doing a bunch of non-standard stuff xlwings/xlwings/_xlwindows.py at 8137da169dd1e5550ac65e302609c07468743755 · xlwings/xlwings · GitHub so maybe it picks up the pywin32 that’s already in Rhino’s CPython3?
I’m happy to believe that xlwings does its imports the way it does for a good reason. But at the end of the day, there’s not much more to a .xlsx file than a zipped xml file. So if the xlwings team aren’t going to support running in Rhino’s Pythons and others, (even for customers on their $1490 a year professional plan) I’d recommend people choose an alternative library without these issues.
I’ve had good results using: Welcome to pylightxl documentation — pylightxl 2019 documentation and made a fork for Iron Python (that only changes one character, to use a different core xml lib). I found the advice in this site to be useful: https://www.python-excel.org/