Міграція з python-calamine (і calamine)
calamine — високоповажний Rust-рідер XLSX/XLS; python-calamine — його Python-біндинг. Обидва зосереджені виключно на таблицях.
Office Oxide у 2,8 рази швидший за python-calamine на XLSX (5,0 мс проти 13,9 мс у середньому на 1 802 файлах), з найвищою часткою успіху (97,8% проти 96,6%). Він також додає повну підтримку DOCX, PPTX та застарілих DOC/PPT — форматів, які calamine взагалі не читає.
Коли мігрувати
Перемикайтеся, якщо щось із цього про вас:
- Потрібні також
.docx/.pptx/.doc/.ppt(calamine — лише XLSX/XLS) - Хочете ширший набір можливостей: вивід у Markdown / HTML, структурований IR, шаблонізація через
EditableDocument - Частка успіху важливіша за незначну перевагу calamine за продуктивністю в окремих сценаріях
- Ви на Python-біндингу і хочете менше конверсій через FFI
Залишайтеся на calamine, якщо:
- Ви читаєте тільки
.xlsxі.xls - Залежите від специфічних для calamine API (
Reader::with_header_row,worksheet_range_atтощо) - Потрібні вирази формул (calamine їх надає; IR Office Oxide — ні)
Встановлення (Python)
pip uninstall python-calamine
pip install office-oxide
Встановлення (Rust)
# Cargo.toml
[dependencies]
# Замінити:
# calamine = "0.30"
office_oxide = "0.1.0"
Порівняльна шпаргалка — Python
Відкрити робочу книгу
python-calamine
from python_calamine import CalamineWorkbook
wb = CalamineWorkbook.from_path("budget.xlsx")
office_oxide
from office_oxide import Document
with Document.open("budget.xlsx") as doc:
...
Ітерація по аркушах
python-calamine
for name in wb.sheet_names:
sheet = wb.get_sheet_by_name(name)
for row in sheet.to_python():
print(row)
office_oxide
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)
Прочитати один аркуш як рядки
python-calamine
sheet = wb.get_sheet_by_name("Q4")
rows = sheet.to_python()
office_oxide
with Document.open("budget.xlsx") as doc:
table = next(
el for section in doc.to_ir()["sections"]
if section.get("title") == "Q4"
for el in section["elements"] if el["kind"] == "Table"
)
rows = table["rows"]
Більш прямий шлях:
with Document.open("budget.xlsx") as doc:
sheet = doc.as_xlsx().sheet("Q4")
rows = sheet.rows() # list[list[str]]
Імена аркушів
python-calamine
print(wb.sheet_names)
office_oxide
with Document.open("budget.xlsx") as doc:
print([s.name() for s in doc.as_xlsx().sheets()])
Порівняльна шпаргалка — Rust
Відкрити й проітерувати
calamine
use calamine::{open_workbook, Xlsx, Reader};
let mut wb: Xlsx<_> = open_workbook("budget.xlsx")?;
for sheet_name in wb.sheet_names() {
if let Ok(range) = wb.worksheet_range(&sheet_name) {
for row in range.rows() {
println!("{row:?}");
}
}
}
office_oxide
use office_oxide::Document;
let doc = Document::open("budget.xlsx")?;
if let Some(xlsx) = doc.as_xlsx() {
for sheet in xlsx.sheets() {
for cell in sheet.cells() {
println!("{}: {:?}", cell.address(), cell.value());
}
}
}
Формат-незалежний IR (у calamine еквівалента немає)
let doc = Document::open("budget.xlsx")?;
let ir = doc.to_ir();
serde_json::to_writer(std::io::stdout(), &ir)?;
Форма виходу така сама, як із .docx чи .pptx — корисно, коли даунстрім-споживачам не треба знати вихідний формат.
Записи в XLSX
calamine — лише для читання. Office Oxide пише клітинки XLSX через EditableDocument:
from office_oxide import EditableDocument
with EditableDocument.open("budget.xlsx") as ed:
ed.set_cell(0, "B5", 42_000)
ed.save("budget.xlsx")
Для повноцінної збірки XLSX спускайтеся в xlsx::create::XlsxBuilder або використовуйте umya-spreadsheet / rust_xlsxwriter.
Продуктивність
| Бібліотека | XLSX Середнє | p99 | Частка успіху |
|---|---|---|---|
| office_oxide | 5,0 мс | 40 мс | 97,8% |
| python-calamine | 13,9 мс | 183 мс | 96,6% |
| openpyxl | 94,5 мс | 698 мс | 96,2% |
| Бібліотека | XLS Середнє | p99 | Частка успіху |
|---|---|---|---|
| office_oxide | 2,8 мс | 75 мс | 99,2% |
| python-calamine | 9,0 мс | 96 мс | 90,7% |
Чим відрізняються
calamine повертає типізований Data-enum на клітинку (Int, Float, String, Bool, DateTime, Empty, Error). IR Office Oxide згортає значення в рядки; для типізованого доступу до клітинок використовуйте формат-специфічний аксесор:
with Document.open("budget.xlsx") as doc:
for sheet in doc.as_xlsx().sheets():
for cell in sheet.cells():
print(cell.value(), cell.value_type()) # value_type: "string" | "number" | "boolean" | "empty"
Див. також
- Міграція з openpyxl — для користувачів openpyxl
- Міграція з xlrd — для користувачів застарілого
.xls - Бенчмарки продуктивності