Skip to content

Migração a partir do xlrd

O xlrd era a biblioteca Python padrão para ler arquivos .xls legados (Excel 97–2003). Ele removeu o suporte a .xls na versão 2.0 (2020) e recomenda a migração. As soluções da comunidade — fixar xlrd<2.0, chamar o LibreOffice, mudar para python-calamine — têm suas ressalvas.

O Office Oxide lê .xls diretamente, 13× mais rápido que a última versão do xlrd com suporte a .xls, com maior taxa de sucesso. De bônus, também dá para converter .xls.xlsx em uma linha.

Quando migrar

Troque se qualquer uma destas condições se aplica:

  • Você ainda está em xlrd<2.0 e quer uma biblioteca com manutenção
  • Precisa de .xls e .xlsx a partir de uma única biblioteca
  • Quer migrar o corpus para .xlsx de uma vez e parar de lidar com o formato legado
  • Também precisa de .doc, .ppt, .docx ou .pptx — cobertos pela mesma instalação

Instalação

pip uninstall xlrd
pip install office-oxide

Guia rápido lado a lado

Abrir um .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]

Iterar células

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())

Ler todas as células como uma tabela (caso mais comum)

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()

# Primeira planilha → primeira seção → primeira tabela
table = next(el for el in ir["sections"][0]["elements"] if el["kind"] == "Table")
rows = table["rows"]

Nomes das planilhas

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()])

Converter .xls → .xlsx (uma linha)

Se o ferramental downstream já fala .xlsx, o caminho de migração mais limpo é converter o corpus uma vez e nunca mais tocar em .xls:

from office_oxide import Document

with Document.open("legacy.xls") as doc:
    doc.save_as("modern.xlsx")

Para um diretório inteiro:

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)

Desempenho

Biblioteca .xls Média p99 Taxa de sucesso
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%

O Office Oxide é 13× mais rápido que o xlrd e tem 6,1 pontos percentuais a mais de taxa de sucesso.

O que se perde

Expressões de fórmula, nomes definidos e caches de fórmula compartilhada do xlrd não são expostos via IR. Resultados em cache das fórmulas sobrevivem — é isso que a maioria das ferramentas downstream de fato precisa. Para as expressões, desça até o módulo xls específico do formato ou converta para .xlsx e use xlsx.

Veja também