从 xlrd 迁移
xlrd 曾是读取遗留 .xls(Excel 97–2003)文件的标准 Python 库。它在 2.0(2020)中砍掉了 .xls 支持并建议迁移。社区的各种绕行方案 — 锁 xlrd<2.0、调用 LibreOffice、改用 python-calamine — 都有各自的缺点。
Office Oxide 直接读取 .xls,比 xlrd 最后一个支持 .xls 的版本快 13 倍,通过率也更高。附带的好处是你还能用一行代码把 .xls 转成 .xlsx。
何时迁移
下列任一条成立就切换:
- 你还停留在
xlrd<2.0上,想用一个有维护的库 - 你需要从一个库里同时读
.xls和.xlsx - 你想把整个语料一次性迁到
.xlsx,从此告别遗留格式 - 你还需要
.doc、.ppt、.docx或.pptx— 同一个安装全覆盖
安装
pip uninstall xlrd
pip install office-oxide
对照速查
打开 .xls
xlrd
import xlrd
book = xlrd.open_workbook("legacy.xls")
sheet = book.sheet_by_index(0)
office_oxide
from office_oxide import Document
with Document.open("legacy.xls") as doc:
xls = doc.as_xls()
sheet = xls.sheets()[0]
遍历单元格
xlrd
for row in range(sheet.nrows):
for col in range(sheet.ncols):
print(sheet.cell_value(row, col))
office_oxide
for cell in sheet.cells():
print(cell.address(), cell.value())
把所有单元格读为一张表(最常见的场景)
xlrd
import xlrd
book = xlrd.open_workbook("legacy.xls")
sheet = book.sheet_by_index(0)
rows = [
[sheet.cell_value(r, c) for c in range(sheet.ncols)]
for r in range(sheet.nrows)
]
office_oxide
from office_oxide import Document
with Document.open("legacy.xls") as doc:
ir = doc.to_ir()
# 第一张工作表 → 第一个章节 → 第一张表
table = next(el for el in ir["sections"][0]["elements"] if el["kind"] == "Table")
rows = table["rows"]
工作表名
xlrd
book = xlrd.open_workbook("legacy.xls")
print(book.sheet_names())
office_oxide
with Document.open("legacy.xls") as doc:
print([s.name() for s in doc.as_xls().sheets()])
一行搞定 .xls → .xlsx
如果下游工具已经能处理 .xlsx,最干净的迁移路径就是一次性把语料转过去,从此不再碰 .xls:
from office_oxide import Document
with Document.open("legacy.xls") as doc:
doc.save_as("modern.xlsx")
整个目录:
from pathlib import Path
from office_oxide import Document
for src in Path("legacy").rglob("*.xls"):
dst = src.with_suffix(".xlsx")
with Document.open(src) as doc:
doc.save_as(dst)
性能
| 库 | .xls 平均 |
p99 | 通过率 |
|---|---|---|---|
| office_oxide | 2.8 ms | 75 ms | 99.2% |
| python-calamine | 9.0 ms | 96 ms | 90.7% |
| xlrd | 36.6 ms | 503 ms | 93.1% |
Office Oxide 比 xlrd 快 13 倍,通过率高 6.1 个百分点。
会丢失什么
xlrd 的公式表达式、已定义名称和共享公式缓存不会通过 IR 暴露。缓存的公式结果会保留 — 这正是下游工具真正需要的东西。要拿公式表达式,请下沉到格式专用的 xls 模块,或先转成 .xlsx 再用 xlsx。
相关链接
- 从 openpyxl 迁移 — 针对
.xlsx - 转换:遗留格式 → OOXML —
save_as做了什么 - 性能基准