Last modified: Nov 20, 2025 By Alexander Williams
Migrate from Python xlrd to openpyxl Safely
Python developers face a crucial migration. The xlrd library no longer supports modern Excel files. This guide helps you transition to openpyxl safely.
Why Migrate from xlrd to openpyxl?
xlrd was the go-to library for reading Excel files. But it stopped supporting .xlsx files in version 2.0.0. This creates compatibility issues.
openpyxl is the modern solution. It supports both reading and writing Excel files. It handles .xlsx format natively and receives regular updates.
Many existing projects still use xlrd. They need careful migration to avoid breaking changes. This process requires planning and testing.
Key Differences Between xlrd and openpyxl
Understanding the differences is crucial. xlrd uses 0-based indexing for rows and columns. openpyxl uses 1-based indexing like Excel.
xlrd has different data type handling. It returns specific types for dates and numbers. openpyxl handles these differently.
The API structure varies significantly. Method names and object hierarchies differ. You must update your code accordingly.
If you previously used xlrd for automating Excel reporting, you'll need to adapt your approach with openpyxl.
Installation and Setup
First, install openpyxl using pip. Remove xlrd if you're replacing it completely.
pip install openpyxl
pip uninstall xlrd
Basic Reading Operations
Let's compare basic file reading. Here's the xlrd approach:
import xlrd
# xlrd code
workbook = xlrd.open_workbook('file.xlsx')
sheet = workbook.sheet_by_index(0)
cell_value = sheet.cell_value(0, 0) # 0-based indexing
Now the equivalent openpyxl code:
import openpyxl
# openpyxl code
workbook = openpyxl.load_workbook('file.xlsx')
sheet = workbook.active # or workbook['SheetName']
cell_value = sheet.cell(row=1, column=1).value # 1-based indexing
The load_workbook function replaces xlrd's open_workbook. Notice the 1-based indexing in openpyxl.
Working with Multiple Sheets
Handling multiple sheets differs between libraries. xlrd uses sheet indices or names.
# xlrd multiple sheets
workbook = xlrd.open_workbook('file.xlsx')
sheet1 = workbook.sheet_by_index(0)
sheet2 = workbook.sheet_by_name('Data')
openpyxl provides more intuitive sheet access:
# openpyxl multiple sheets
workbook = openpyxl.load_workbook('file.xlsx')
sheet1 = workbook.worksheets[0]
sheet2 = workbook['Data']
sheet_names = workbook.sheetnames
For complex projects that work with multiple Excel sheets, openpyxl offers better sheet management.
Cell Value Access Patterns
Accessing cell values requires careful migration. xlrd uses row and column indices.
# xlrd cell access
value1 = sheet.cell_value(0, 0) # A1
value2 = sheet.cell(0, 0).value # Alternative
openpyxl offers multiple access methods:
# openpyxl cell access
value1 = sheet.cell(row=1, column=1).value # A1
value2 = sheet['A1'].value # Excel notation
value3 = sheet['A1'] # Returns cell object
The cell method in openpyxl is most similar to xlrd's approach. But remember the 1-based indexing difference.
Handling Data Types
Data type handling differs significantly. xlrd automatically converts Excel types to Python types.
# xlrd data types
import xlrd
workbook = xlrd.open_workbook('dates.xlsx')
sheet = workbook.sheet_by_index(0)
date_value = sheet.cell_value(0, 0) # Returns datetime
openpyxl requires explicit type handling:
# openpyxl data types
import datetime
workbook = openpyxl.load_workbook('dates.xlsx')
sheet = workbook.active
cell_value = sheet['A1'].value
if isinstance(cell_value, datetime.datetime):
processed_date = cell_value
This is important when you need to read Excel formulas and values correctly in your new implementation.
Iterating Through Rows and Columns
Row and column iteration patterns change. xlrd uses range-based iteration.
# xlrd iteration
for row_index in range(sheet.nrows):
for col_index in range(sheet.ncols):
value = sheet.cell_value(row_index, col_index)
openpyxl uses more Pythonic iteration:
# openpyxl iteration
for row in sheet.iter_rows(values_only=True):
for cell_value in row:
process_value(cell_value)
# Alternative with indices
for row in sheet.iter_rows(min_row=1, max_row=10):
for cell in row:
value = cell.value
The iter_rows method provides flexible row iteration. Use values_only=True to get values directly.
Writing Excel Files
openpyxl adds writing capability that xlrd lacked. This is a major advantage.
# openpyxl writing
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet['A1'] = 'Hello'
sheet.cell(row=2, column=1, value='World')
workbook.save('output.xlsx')
Migration Strategy and Best Practices
Plan your migration carefully. Start with a thorough code audit. Identify all xlrd usage in your project.
Create a migration wrapper if needed. This can help transition gradually. It wraps openpyxl with xlrd-like interface.
Test extensively with your actual Excel files. Verify data types and formatting. Check formulas and calculations.
Update your documentation and comments. Ensure team members understand the changes. Provide training if necessary.
Common Migration Issues and Solutions
Index errors are common. Remember the 1-based vs 0-based indexing difference. This causes off-by-one errors.
Date handling changes can break date calculations. Test date-related functionality thoroughly after migration.
Empty cell detection differs. xlrd returns empty strings. openpyxl returns None for empty cells.
If you encounter issues, our guide on debugging Python xlrd errors might help identify similar patterns in openpyxl.
Testing Your Migration
Create comprehensive test cases. Compare outputs between xlrd and openpyxl. Ensure they match exactly.
def test_migration():
# Test with sample file
xlrd_values = get_xlrd_values('test.xlsx')
openpyxl_values = get_openpyxl_values('test.xlsx')
assert xlrd_values == openpyxl_values, "Migration failed"
Performance Considerations
openpyxl can be memory-intensive for large files. Use read-only mode for better performance.
# Memory-efficient reading
workbook = openpyxl.load_workbook('large_file.xlsx', read_only=True)
For write-intensive operations, use write-only mode. This improves performance significantly.
Conclusion
Migrating from xlrd to openpyxl is essential for modern Excel processing. The transition requires careful planning and testing.
Focus on indexing differences and data type handling. Test thoroughly with your specific use cases. The benefits outweigh the migration effort.
openpyxl offers better compatibility and additional features. Your investment in migration will pay off with more robust Excel processing.