一、前言:Excel 與 Python 的不解之緣

在數據處理與辦公自動化領域,Excel 文件(.xls / .xlsx) 一直是最常見的數據載體。
而在 Python 世界中,圍繞 Excel 操作的生態非常龐大,其中最經典、最輕量級的讀文件庫之一便是 —— xlrd

xlrd 是一個專門用於讀取 Excel 文件內容的 Python 庫,它支持從 Excel 工作簿中提取工作表(Sheet)、單元格內容、數據類型等信息。
雖然在新版本中它僅支持舊格式 .xls 文件,但憑藉其簡潔、高效和穩定的特點,xlrd 依然在許多老系統與數據遷移任務中被廣泛使用。


二、庫的起源與演變:從萬能到專一

在早期的 Python Excel 生態中,xlrdxlwt(寫入)是一對黃金搭檔,配合使用可以輕鬆實現 Excel 的讀寫操作。

  • xlrd(read):讀取 Excel 文件內容。
  • xlwt(write):寫入 .xls 文件。
  • xlutils:基於二者實現的高級操作庫(複製、修改工作表等)。

然而,自 xlrd 2.0.0

🚫 不再支持 .xlsx 文件讀取,僅支持 Excel 97-2003 格式 .xls

主要原因包括:

  1. Excel 2007 之後的 .xlsx 文件是基於 XML + ZIP 的複雜結構,解析成本高;
  2. 已有更現代的庫如 openpyxlpandas 提供更好的支持;
  3. 維護者希望 xlrd 聚焦舊格式的穩定讀取。

這也導致了後期許多項目遷移至 openpyxlpandas.read_excel()
不過,如果你面對的是歷史系統、銀行報表、政府舊數據,xlrd 仍然是最輕量可靠的解決方案。


三、安裝與環境要求

1. 安裝方式

pip install xlrd

2. 版本建議

如果你的 Excel 文件是 .xlsx 格式,請務必使用舊版本(≤1.2.0):

pip install xlrd==1.2.0

否則會遇到如下錯誤:

XLRDError: Excel xlsx file; not supported

3. 基本依賴

xlrd 只依賴標準庫和 zipfile 模塊,因此即使在嵌入式系統(如樹莓派、Jetson Nano)上也能輕鬆運行。


四、核心對象結構分析

xlrd 的內部設計採用了典型的分層數據結構,理解這點有助於掌握其靈活性:

層級

對象名稱

描述

1

Book

Excel 文件對象(工作簿)

2

Sheet

每個工作表

3

Cell

單元格對象(包含值與類型)

4

XFRecord

樣式記錄對象(字體、邊框、格式等)

這種結構類似於文檔樹(Document Object Model),讀取 Excel 時,xlrd 會逐級解析:

import xlrd

workbook = xlrd.open_workbook("data.xls")
sheet = workbook.sheet_by_index(0)
value = sheet.cell_value(0, 0)
print(value)

執行結果:

員工編號

五、主要API與使用方法詳解

1. 打開 Excel 文件

import xlrd
book = xlrd.open_workbook("report.xls")

支持參數:

  • filename: 文件路徑
  • file_contents: 二進制字節流
  • encoding_override: 指定編碼(如 GBK)
  • on_demand: 是否懶加載(節省內存)
  • ragged_rows: 是否允許行列不對齊

2. 獲取工作表

# 通過索引
sheet = book.sheet_by_index(0)

# 通過名稱
sheet = book.sheet_by_name('銷售數據')

# 獲取所有表名
print(book.sheet_names())

3. 獲取單元格內容與屬性

value = sheet.cell_value(1, 2)  # 第二行第三列
ctype = sheet.cell_type(1, 2)   # 數據類型

常見的 ctype 類型:

類型編號

類型名

含義

0

XL_CELL_EMPTY

空單元格

1

XL_CELL_TEXT

字符串

2

XL_CELL_NUMBER

數值

3

XL_CELL_DATE

日期

4

XL_CELL_BOOLEAN

布爾值

5

XL_CELL_ERROR

錯誤


4. 遍歷所有數據

for row_idx in range(sheet.nrows):
    row = sheet.row_values(row_idx)
    print(row)

或者使用 get_rows()

for row in sheet.get_rows():
    print([cell.value for cell in row])

5. 日期類型的處理

Excel 內部使用浮點數存儲日期,需要藉助 xlrd.xldate_as_datetime() 進行轉換:

from datetime import datetime
date_value = sheet.cell_value(2, 3)
date_obj = xlrd.xldate_as_datetime(date_value, book.datemode)
print(date_obj.strftime("%Y-%m-%d"))

六、實戰案例:Excel 數據提取與分析

下面通過一個實際案例展示如何利用 xlrd 實現報表數據分析。

案例背景

某公司每月導出一份 sales_2024.xls 銷售報表,包含以下字段:

日期

產品

銷量

單價

地區

2024-01-01

A類產品

120

30

上海

2024-01-02

B類產品

80

25

北京

目標

  1. 計算各產品的總銷售額
  2. 輸出每個地區的總銷售額分佈

步驟1:讀取數據

import xlrd

book = xlrd.open_workbook('sales_2024.xls')
sheet = book.sheet_by_index(0)

data = []
for row_idx in range(1, sheet.nrows):
    row = sheet.row_values(row_idx)
    data.append(row)

步驟2:計算彙總

from collections import defaultdict

product_sales = defaultdict(float)
region_sales = defaultdict(float)

for row in data:
    product = row[1]
    sales = row[2] * row[3]
    region = row[4]
    product_sales[product] += sales
    region_sales[region] += sales

print("按產品統計:", dict(product_sales))
print("按地區統計:", dict(region_sales))

輸出結果:

按產品統計: {'A類產品': 3600.0, 'B類產品': 2000.0}
按地區統計: {'上海': 3600.0, '北京': 2000.0}

步驟3:可視化展示(與 Matplotlib 結合)

import matplotlib.pyplot as plt

plt.bar(product_sales.keys(), product_sales.values())
plt.title("產品銷售額對比")
plt.xlabel("產品")
plt.ylabel("銷售額(元)")
plt.show()

這展示了 xlrd 在數據提取階段的強大能力,與現代可視化庫完美兼容。


七、性能優化與大文件讀取

當 Excel 文件行數超過 10 萬行時,內存開銷會顯著上升。
以下技巧可幫助提升性能:

1. 啓用按需加載

book = xlrd.open_workbook('large.xls', on_demand=True)

僅在訪問某個 Sheet 時加載數據,可顯著節省內存。

2. 避免重複讀取單元格對象

使用 row_values() 一次性獲取整行數據,而非多次調用 cell_value()

3. 文件格式轉換

若文件超過幾百 MB,建議先用命令行或 pandas 轉為 CSV 再分析:

import pandas as pd
df = pd.read_excel('large.xls', engine='xlrd')
df.to_csv('large.csv', index=False)

八、與其他庫的比較

功能點

xlrd

openpyxl

pandas

支持文件格式

.xls

.xlsx

.xls + .xlsx

讀取速度

快(小文件)

稍慢

中等

內存佔用

較低

較高

中等

寫入能力




API 難度

簡單

中等

簡單

適合場景

老系統兼容、輕量提取

現代 Excel 操作

分析任務

總結:

  • 如果你只需讀取 .xls 文件:xlrd
  • 如果需要寫入或支持 .xlsxopenpyxl
  • 如果需要快速分析:pandas.read_excel()

九、深入源碼:xlrd 的解析機制

xlrd 的核心邏輯位於 book.pysheet.py 模塊。其工作流程大致為:

  1. 打開文件 → 識別格式(OLE2 vs XML)
  2. 解析 Workbook → Sheet → Cell
  3. 建立數據緩存與索引表
  4. 提供 Pythonic API 封裝訪問

核心函數結構如下:

def open_workbook(filename=None, file_contents=None, encoding_override=None, ...):
    bk = Book()
    bk.load(filename)
    return bk

Book 類中維護 sheets 列表,每個 Sheet 又包含 _cell_values 數組和 _cell_types 數組,用於快速索引。
這種結構雖然不如 pandas 靈活,但勝在內存可控和結構清晰。


十、版本兼容與遷移策略

1. xlrd >= 2.0 不支持 .xlsx

對於 .xlsx 文件,請使用:

import pandas as pd
df = pd.read_excel('file.xlsx', engine='openpyxl')

2. 向下兼容舊系統

若必須兼容 .xls.xlsx

try:
    book = xlrd.open_workbook('data.xlsx')
except Exception:
    import openpyxl
    wb = openpyxl.load_workbook('data.xlsx')

3. 推薦替代方案

  • 讀取 .xlsxlrd
  • 寫入 .xlsxlwt
  • 讀取/寫入 .xlsxopenpyxl
  • 分析型任務:pandas

十一、實際應用案例:自動報表系統

在許多中小企業中,日報/週報 Excel 報表往往手動彙總。使用 xlrd 可實現自動提取並生成彙總結果。

示例流程:

  1. 掃描 ./reports 文件夾下所有 .xls 文件
  2. 讀取每個文件中的“銷售額”數據
  3. 彙總後生成一份統計表(通過 xlwt 寫出)
import os, xlrd, xlwt

summary = xlwt.Workbook()
sheet_sum = summary.add_sheet('彙總')

row_index = 0
for file in os.listdir('./reports'):
    if file.endswith('.xls'):
        wb = xlrd.open_workbook(os.path.join('./reports', file))
        sh = wb.sheet_by_index(0)
        total = sum(sh.col_values(2)[1:])  # 第三列為銷售額
        sheet_sum.write(row_index, 0, file)
        sheet_sum.write(row_index, 1, total)
        row_index += 1

summary.save('彙總結果.xls')

這就是最典型的辦公自動化應用之一。


十二、常見錯誤與排查

錯誤類型

説明

解決方法

XLRDError: Excel xlsx file; not supported

新版本不支持 .xlsx

降級至 xlrd==1.2.0

FileNotFoundError

文件路徑錯誤

檢查路徑、使用絕對路徑

IndexError: list index out of range

Sheet 索引錯誤

確認工作表存在

UnicodeDecodeError

編碼問題

指定 encoding_override="gbk"


十三、與 Pandas 的結合:批量數據分析

pandasread_excel() 默認會使用 xlrd(舊版本),因此你可以結合兩者快速分析數據:

import pandas as pd
df = pd.read_excel('report.xls', engine='xlrd')
print(df.describe())

對於 .xlsx 文件:

df = pd.read_excel('report.xlsx', engine='openpyxl')

十四、總結與展望

xlrd 雖然是一個“老派”庫,但它依然具備以下優勢:

✅ 輕量級、穩定性高
✅ 適合服務器端、嵌入式環境
✅ 兼容老式 Excel 格式
✅ 代碼簡單易嵌入腳本

在現代 Python 數據分析生態中,xlrd 更多地扮演**“穩定讀取引擎”**的角色,而非“通用 Excel 工具”。
對於大多數歷史數據處理、Excel 自動化遷移任務而言,它仍然是一款值得信賴的老朋友。


參考資源

  • 官方文檔:https://github.com/python-excel/xlrd
  • 兼容庫:openpyxl
  • 高級分析:pandas.read_excel()