从 openpyxl 迁移
Office Oxide 读取 XLSX 比 openpyxl 快 18 倍(1,802 个文件,平均 5.0 ms 对 94.5 ms),通过率高于所有测试过的库。它还能直接读取遗留 .xls — openpyxl 根本做不到。
何时迁移
如果你在做下列任何一项,就切换:
- 从
.xlsx读取单元格、行、工作表或表格用于数据摄取 / RAG / 仪表盘 - 将电子表格转换为 Markdown 或 HTML
- 需要
.xls支持,但不想添加xlrd(自 2.0 起已弃用)或调用 LibreOffice - 想用同一个库处理
.docx、.pptx或遗留 DOC/PPT - 用
EditableDocument在模板中写单元格
继续用 openpyxl 的场景:
- 从头构建包含图表、条件格式、命名样式和透视表的复杂 XLSX(openpyxl 是功能最全的纯 Python 创建选项)
- 需要在纯 Python 中计算公式
安装
pip uninstall openpyxl
pip install office-oxide
对照速查
打开工作簿
openpyxl
from openpyxl import load_workbook
wb = load_workbook("budget.xlsx", data_only=True)
office_oxide
from office_oxide import Document
with Document.open("budget.xlsx") as doc:
...
遍历工作表单元格
openpyxl
from openpyxl import load_workbook
wb = load_workbook("budget.xlsx", data_only=True)
for sheet in wb.worksheets:
for row in sheet.iter_rows(values_only=True):
print(row)
office_oxide
from office_oxide import Document
with Document.open("budget.xlsx") as doc:
ir = doc.to_ir()
for section in ir["sections"]:
print(f"# {section.get('title')}")
for el in section["elements"]:
if el["kind"] == "Table":
for row in el["rows"]:
print(row)
需要更丰富的逐单元格访问(类型、公式、合并单元格)时,下沉到 XLSX 模块:
with Document.open("budget.xlsx") as doc:
xlsx = doc.as_xlsx()
for sheet in xlsx.sheets():
for cell in sheet.cells():
print(cell.address(), cell.value(), cell.value_type())
读取单个单元格
openpyxl
wb = load_workbook("budget.xlsx", data_only=True)
sheet = wb["Q4"]
val = sheet["B5"].value
office_oxide
with Document.open("budget.xlsx") as doc:
val = doc.as_xlsx().sheet("Q4").cell("B5").value()
写入单元格(模板化)
openpyxl
from openpyxl import load_workbook
wb = load_workbook("template.xlsx")
ws = wb["Summary"]
ws["A1"] = "Total"
ws["B1"] = 42.5
ws["C1"] = True
wb.save("filled.xlsx")
office_oxide
from office_oxide import EditableDocument
with EditableDocument.open("template.xlsx") as ed:
ed.set_cell(0, "A1", "Total") # sheet 0 = 第一个工作表
ed.set_cell(0, "B1", 42.5)
ed.set_cell(0, "C1", True)
ed.save("filled.xlsx")
sheet_index 从零开始;cell_ref 使用标准 A1 记法。要把工作表名解析为索引,先读取工作簿并调用 sheets()。
转换为 Markdown / HTML
openpyxl — 没有内置;需要自己渲染行。
office_oxide
with Document.open("budget.xlsx") as doc:
md = doc.to_markdown() # 每个工作表一个 ## 章节,GFM 表格
读取工作表名
openpyxl
wb = load_workbook("budget.xlsx")
print(wb.sheetnames)
office_oxide
with Document.open("budget.xlsx") as doc:
print([s.name() for s in doc.as_xlsx().sheets()])
读取遗留 .xls
openpyxl 打不开 .xls。历史上的替代方案是 xlrd,自 2.0 起对 .xls 弃用,已无人维护。
office_oxide
from office_oxide import Document
with Document.open("legacy.xls") as doc:
print(doc.plain_text())
doc.save_as("modern.xlsx") # 一行完成迁移
性能
| 库 | 平均 | p99 | 通过率 |
|---|---|---|---|
| office_oxide | 5.0 ms | 40 ms | 97.8% |
| python-calamine | 13.9 ms | 183 ms | 96.6% |
| openpyxl | 94.5 ms | 698 ms | 96.2% |
每天读 10 万个电子表格的典型分析流水线:openpyxl 需要 8 小时 18 分,office_oxide 只要 26 分钟。
会丢失什么
EditableDocument.set_cell 写入原始单元格值;不会修改数字格式、条件格式、图表或命名区域(这些部分会原样保留)。要构建带完整样式的 XLSX,请用 openpyxl,或下沉到 office_oxide.xlsx::create::XlsxBuilder。
相关链接
- 设置 XLSX 单元格 — 完整的类型矩阵和边缘情况
- 从 xlrd 迁移 — 针对遗留
.xls - 性能基准