Reading Excel Files with readxl and writexl

· 3 min read · Updated March 12, 2026 · beginner
r excel data-import readxl writexl

If you work with data in R, at some point you will need to read Excel files. Excel remains the default format for sharing data in many industries, and the readxl package makes it straightforward to import that data without external dependencies.

Install readxl and writexl

Both packages come from the tidyverse ecosystem and install with a single command:

install.packages("readxl")
install.packages("writexl")

No Java, no system dependencies. Just load the packages and start working:

library(readxl)
library(writexl)

Read Excel Files

The main function you will use is read_excel(). It automatically detects the file format (.xls or .xlsx) and handles both legacy and modern Excel files.

# Basic usage - reads first sheet by default
df <- read_excel("data.xlsx")

Reading Different Sheets

Excel workbooks often contain multiple sheets. You can specify which sheet to read by name or position:

# By sheet name
df <- read_excel("data.xlsx", sheet = "Sales")

# By sheet position (1 = first sheet)
df <- read_excel("data.xlsx", sheet = 1)

Reading Cell Ranges

Sometimes you only need a portion of a worksheet. Use the range argument with Excel notation:

# Read cells A1:D10
df <- read_excel("data.xlsx", range = "A1:D10")

# Read from a named range
df <- read_excel("data.xlsx", range = "Sheet1!B2:F20")

Controlling Column Types

By default, readxl guesses column types from the data. You can override this with the col_types argument:

# Specify all columns as character
df <- read_excel("data.xlsx", col_types = "text")

# Specify per-column types
df <- read_excel("data.xlsx", 
                 col_types = c("text", "numeric", "date", "skip"))

Available types: “logical”, “numeric”, “date”, “text”, and “skip”.

Handling Headers

The first row is treated as column names by default. Turn this off to get raw data:

# No header row
df <- read_excel("data.xlsx", col_names = FALSE)

# Use custom names
df <- read_excel("data.xlsx", 
                 col_names = c("ID", "Name", "Value", "Notes"))

Write Excel Files

The writexl package provides write_xlsx() for creating Excel files:

# Write a data frame to Excel
write_xlsx(df, "output.xlsx")

Writing Multiple Sheets

Create a named list of data frames to write multiple sheets:

# Multiple sheets in one file
sheets <- list(
  "Sales" = sales_df,
  "Inventory" = inventory_df,
  "Summary" = summary_df
)

write_xlsx(sheets, "report.xlsx")

Working with Named Regions

Named regions make your code more readable. Reference them directly:

# Read a named region
df <- read_excel("data.xlsx", range = "MyNamedRange")

Listing Sheet Contents

Before reading, inspect what is available in a workbook:

# Get sheet names
excel_sheets("data.xlsx")

# Returns: [1] "Sheet1" "Sheet2" "Q1 Data"

Best Practices and Common Pitfalls

Watch for empty cells: Excel cells can be truly empty, blank strings, or NA. readxl represents these as NA by default.

Date handling: Dates in Excel are stored as numbers (days since 1899-12-30). readxl converts these automatically, but verify the results for your specific locale.

Avoid formula cells: read_excel() reads the calculated values, not the formulas. If you need formulas, use the openxlsx package instead.

Large files: For files with thousands of rows, consider reading only what you need using the range argument to reduce memory usage.

Character encoding: If you see strange characters, the file may use a different encoding. Check the source Excel file encoding settings.

Summary

The readxl package handles most Excel import scenarios without configuration. The writexl package covers the essential export needs. Together, they form a lightweight, dependency-free solution for working with Excel files in R.

See Also