Create Professional Reports in Excel using R and XLSX

While R is the real workhorse of data analysis and modeling, if you want to share the results of your work with other people your probably going to send it in a spreadsheet. Luckily the xlsx package for R makes it easy to export simple spreadsheets and also has advanced functionality to create workbooks with professional design and formatting.

Requirements and installation

In order to create Excel workbooks from R, we are going to use the xlsx package. You can install it using the following command:

install.packages("xlsx")

In addition to having the xlsx package installed, you also need to have the correct version of Java installed for your system (either 32 or 64 bits).

Working with xlsx

Basic usage

At it’s most basic, xlsx will export a data frame to an Excel worksheet simply by using the write.xlsx function. If you want to write multiple worksheets in a single workbook, use the append=TRUE argument after the first worksheet.

# Load the xlsx package
library("xlsx")

# Write a list of 4 cylinder cars into a worksheet
write.xlsx(mtcars[mtcars$cyl == 4 , ], file="workbook.xlsx", sheetName="4 Cylinder Cars", append=FALSE)

# Add another worksheet with 6 cylinder cars
write.xlsx(mtcars[mtcars$cyl == 6 , ], file="workbook.xlsx", sheetName="6 Cylinder Cars", append=TRUE)

Running the code, R will create an Excel workbook with two worksheets which looks like this:

Customizing your Excel file

That’s all well and nice, but it’s not going to win any beauty awards. The formatting is all based on Excel’s defaults, the column widths are too narrow so that the car names have been cropped, and there’s no description of what this data is (other than the worksheet’s name).

What if you want to add title, comments, or other supplementary information to your workbook? The xlsx package offers the ability to set cell styles and add arbitrary text to cells, in addition to exporting data frames.

Create an empty workbook

To begin we need to create an empty workbook object, which we will be customizing as we go. To create the empty workbook, use the createWorkbook function:

# Load the xlsx package
library("xlsx")

# Create an empty Excel workbook
workbook <- createWorkbook(type="xlsx")

Create cell formats and styles

Next you need to set up the cell formats that you want to use in your file. These formats will define the font, text and background colours, the cell border, and the number formatting for your cells. I’ll set up a few formats for my report based on the default formats in Excel using CellStyle:

# Add a format for the title
titleStyle <- CellStyle(workbook) + Font(workbook, name = "Calibri Light", heightInPoints=18, color="#44546A")

# Add a format for table headings
headingStyle <- CellStyle(workbook) + Font(workbook, name = "Calibri", heightInPoints=11, color="#44546A",  isBold=TRUE) + Border(color="#8EA9DB", position="BOTTOM", pen="BORDER_MEDIUM")

# Add a format for table rows
rowStyle <- CellStyle(workbook) + Font(workbook, name = "Calibri", heightInPoints=11, isBold=TRUE)

# Add a format for comments
commentStyle <<- CellStyle(workbook) + Font(workbook, name = "Calibri", heightInPoints=11, color="#7F7F7F", isItalic=TRUE)

Create a worksheet

Now that the background work has been done, we can start building our workbook. The first step is to create a new worksheet. This is accomplished with createSheet:

# Add a sheet to our workbook
sheet1 <- createSheet(workbook, sheetName = "4 Cylinder Cars")

Add titles to the worksheet

Next we can add titles and other text to the new worksheet. Adding titles using xlsx is actually a four step process:

  1. Create a new row, using createRow and specifying the row number
  2. Create a cell on the new row, using createCell and specifying the column number
  3. Set the cell contents, using setCellValue
  4. Set the cell formatting, using setCellStyle

Let’s go through these steps to add a title to the worksheet and a comment. We’ll move through the entire process twice, once for the title and once for the comment.

# We'll start with adding a title

# First we'll create a new row, let's put the title on row 2
titleRow <-createRow(sheet1, rowIndex=2)
# We'll add a cell to that row (in the first column) for the title
sheetTitle <-createCell(titleRow, colIndex=1)
# We'll add the sheet title to the cell
setCellValue(sheetTitle[[1,1]], "4 Cylinder Cars")
# We'll choose the formatting for the cell
setCellStyle(sheetTitle[[1,1]], titleStyle)

# Now we'll repeat this process to add a comment to the worksheet

# First we'll create a new row, let's put the comment on row 4
titleRow <-createRow(sheet1, rowIndex=4)
# We'll add a cell to that row (in the first column) for the comment
sheetTitle <-createCell(titleRow, colIndex=1)
# We'll add the comment to the cell
setCellValue(sheetTitle[[1,1]], "A listing of all the 4 cylinder cars from the mtcars dataset")
# We'll choose the formatting for the cell
setCellStyle(sheetTitle[[1,1]], commentStyle)

Add a data frame to the worksheet

It’s finally time to write some real data to the worksheet. We’ll do this using the addDataFrame funtion.

Once again we need to specify which row / column we want the data frame to be written in, so you’ll need to keep track of where you are in your worksheet as you add items to it.

You can also specify the style for the first row and first column of your data frame using the colnamesStyle and rownamesStyle arguments.

# Add a data frame to our worksheet
addDataFrame(mtcars[mtcars$cyl == 4 , ], sheet1, startRow=6, startColumn=1, colnamesStyle = headingStyle, rownamesStyle = rowStyle)

Update column widths

By default the columns in the worksheets will be 64 pixels wide, which might be to narrow to display your text correctly. You can change the column widths using the setColumnWidth function and specifying which columns you want to change and what the new width should be:

# Set the width of the first column to be wider so the full car names display
setColumnWidth(sheet1, colIndex=1, colWidth=15)

Add other worksheets

You can add as many other worksheets as you want to your workbook by repeating the steps above to add a worksheet, titles, and data frames.

Save your workbook

Lastly, once the entire workbook has been built, you can save the workbook by running saveWorkbook with the filename you want:

# Save the workbook
saveWorkbook(workbook, "workbook.xlsx")

The results

If you follow the steps listed above, you’ll get a workbook that looks like this:

Which is a lot easier on the eyes than the first example, and includes some additional descriptive text so you know what you’re looking at.

The full code for generating the example above is:

# Load the xlsx package
library("xlsx")

# Create an empty Excel workbook
workbook <- createWorkbook(type="xlsx")

# Add a format for the title
titleStyle <- CellStyle(workbook) + Font(workbook, name = "Calibri Light", heightInPoints=18, color="#44546A")

# Add a format for table headings
headingStyle <- CellStyle(workbook) + Font(workbook, name = "Calibri", heightInPoints=11, color="#44546A",  isBold=TRUE) + Border(color="#8EA9DB", position="BOTTOM", pen="BORDER_MEDIUM")

# Add a format for table rows
rowStyle <- CellStyle(workbook) + Font(workbook, name = "Calibri", heightInPoints=11, isBold=TRUE)

# Add a format for comments
commentStyle <- CellStyle(workbook) + Font( workbook, name = "Calibri", heightInPoints=11, color="#7F7F7F", isItalic=TRUE)

# Add a sheet to our workbook
sheet1 <- createSheet(workbook, sheetName = "4 Cylinder Cars")

# We'll start with adding a title

# First we'll create a new row, let's put the title on row 2
titleRow <-createRow(sheet1, rowIndex=2)
# We'll add a cell to that row (in the first column) for the title
sheetTitle <-createCell(titleRow, colIndex=1)
# We'll add the sheet title to the cell
setCellValue(sheetTitle[[1,1]], "4 Cylinder Cars")
# We'll choose the formatting for the cell
setCellStyle(sheetTitle[[1,1]], titleStyle)

# Now we'll repeat this process to add a comment to the worksheet

# First we'll create a new row, let's put the comment on row 4
titleRow <-createRow(sheet1, rowIndex=4)
# We'll add a cell to that row (in the first column) for the comment
sheetTitle <-createCell(titleRow, colIndex=1)
# We'll add the comment to the cell
setCellValue(sheetTitle[[1,1]], "A listing of all the 4 cylinder cars from the mtcars dataset")
# We'll choose the formatting for the cell
setCellStyle(sheetTitle[[1,1]], commentStyle)

# Add a data frame to our worksheet
addDataFrame(mtcars[mtcars$cyl == 4 , ], sheet1, startRow=6, startColumn=1, colnamesStyle = headingStyle, rownamesStyle = rowStyle)

# Set the width of the first column to be wider so the full car names display
setColumnWidth(sheet1, colIndex=1, colWidth=15)

# Save the workbook
saveWorkbook(workbook, "workbook.xlsx")

What next

While xlsx can make good looking Excel workbooks from within R, it’s hardly convenient. The fact that it takes four lines of code to create a simple title on your worksheet can be aggravating, to say the least. If you’re going to be using xlsx on a regular basis, you’ll probably want to develop some helper functions and libraries to:

  • Script and simplify the actions to create titles and other one-off cells
  • Implement Excel’s default formats, without creating them from scratch in each of your projects

Are you looking for some help automating your reporting or need some ideas of how to take your reporting to the next level? You can reach me using the contact form


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *