Skip to content

Міграція з xlrd

xlrd був стандартною Python-бібліотекою для читання застарілих .xls (Excel 97–2003). У версії 2.0 (2020) він прибрав підтримку .xls і рекомендує мігрувати. Обхідні шляхи спільноти — фіксування xlrd<2.0, виклик LibreOffice, перехід на python-calamine — у кожного свої застереження.

Office Oxide читає .xls напряму, у 13 разів швидше за останній реліз xlrd з підтримкою .xls, і з вищою часткою успіху. Бонусом ви можете конвертувати .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 мс 75 мс 99,2%
python-calamine 9,0 мс 96 мс 90,7%
xlrd 36,6 мс 503 мс 93,1%

Office Oxide у 13 разів швидший за xlrd і має на 6,1 відсоткового пункту вищу частку успіху.

Що втрачається

Вирази формул xlrd, визначені імена та кеші спільних формул не проходять через IR. Кешовані результати формул залишаються — саме це потрібно більшості даунстрім-інструментів. Для самих виразів формул спускайтеся в формат-специфічний модуль xls або конвертуйте в .xlsx і використовуйте xlsx.

Див. також