DevLearningTools

MODULE 13 · LESSON 15

<cfspreadsheet>

Reading, writing, and updating Excel files with cfspreadsheet: its three actions, a real limitation on update, the SpreadsheetNew/SpreadsheetAddRows workflow, and why it's Adobe ColdFusion-only.

New lessons are added one at a time as the course gets built out — a graded quiz for each lesson is still on the way.

cfspreadsheet reads, writes, and updates Excel spreadsheet files (XLS/XLSX) directly in CFML, converting between a query, a spreadsheet object, and the actual file on disk. It's an Adobe ColdFusion tag, Lucee has no native equivalent, though it does offer a related SpreadsheetNew() function.

Learning Objectives

After completing this lesson, you'll be able to:

  • Read an Excel file into a query with cfspreadsheet.
  • Write a new Excel file from a query or a spreadsheet object.
  • Add a sheet to an existing file with update, and know its real limitation.
  • Explain why cfspreadsheet is Adobe ColdFusion-only.

How cfspreadsheet Fits In

Query or Spreadsheet Object

action="read" / "write" / "update"

Excel File (XLS/XLSX)

On Disk or Back Into a Query

A Basic Read Into a Query

Tag Syntax
<cfspreadsheet action="read" src="#expandPath('./employees.xlsx')#" query="employees" headerrow="1">

cfspreadsheet's Attributes

AttributeMeaning
actionread, write, or update (required)
srcFile path to read from (required for read)
filenameOutput file path (required for write/update)
name / queryA variable to hold spreadsheet data, or a query to read from/write to (one is required)
sheet / sheetnameTargets a specific sheet by number or name
headerrowWhich row holds column names, when reading into a query
excludeHeaderRowWhether to leave the header row out of the query result (default false)
columns / rowsLimits reading to a specific range
columnnamesCustom comma-delimited column names, overriding the header row
formatcsv or html, for reading/exporting as something other than a spreadsheet object
overwriteWhether write can replace an existing file (default false)
autosizeAuto-resizes columns to fit content on write (default true)
passwordProtects the file (mandatory for write/update as of the ColdFusion 2025 release)

A Real Example: Building a Spreadsheet Object, Then Writing It

CFScript
theSheet = spreadsheetNew("Sheet1");
spreadsheetAddRows(theSheet, myQuery);
Tag Syntax — Writing It Out
<cfspreadsheet action="write" filename="#expandPath('./mydata.xlsx')#" name="theSheet" overwrite="true">
NOTE

spreadsheetNew() and spreadsheetAddRows() build up an in-memory spreadsheet object first, useful when the data needs shaping before it's actually written, rather than writing a query directly.

A Real Limitation: update Can Only Add Sheets

NOTE

action="update" adds a new sheet to an existing Excel file, it cannot modify a sheet that's already there. Changing existing content means reading the file, making the change to the resulting query or spreadsheet object, and writing it back out.

A Real Gotcha: Password Requirement Since ColdFusion 2025

NOTE

As of the ColdFusion 2025 release, password is mandatory for write and update, code that omitted it on earlier versions needs an explicit password value to keep working.

A Real Limitation: Two Excel 2007 Functions Aren't Supported

NOTE

Adobe's own documentation notes that SpreadSheetAddSplitPane and SpreadSheetAddFreezePane, otherwise part of the same spreadsheet function family, aren't supported for Excel 2007-format files, the two documented exceptions to otherwise full Excel 2007 support.

Why This Tag Doesn't Exist on Lucee

Lucee's own documentation states plainly that cfspreadsheet is not supported by Lucee. It does offer a native SpreadSheetNew() function as a partial alternative, and its own docs point toward community extensions (like spreadsheet-cfml) for the rest of the gap, rather than a built-in tag.

Common Beginner Mistakes

Assuming update can modify an existing sheet's content

It can only add a new sheet. Changing existing content means reading the file, modifying the resulting query or spreadsheet object, and writing it back out.

Porting cfspreadsheet-based code to Lucee unchanged

The tag doesn't exist there at all. Lucee's native SpreadSheetNew() function, or a community extension, is the actual equivalent, not a direct port.

Forgetting the password requirement on ColdFusion 2025

write and update require an explicit password value as of that release, code written against an earlier version may need updating.

Best Practices

  • Use spreadsheetNew()/spreadsheetAddRows() to build a spreadsheet object first when the data genuinely needs shaping before it's written.
  • Set headerrow or columnnames explicitly when reading, rather than relying on default behavior.
  • Check Lucee's SpreadSheetNew() function or a community extension before assuming Adobe cfspreadsheet-based code will run unchanged there.
  • Update code targeting ColdFusion 2025 to supply an explicit password on write/update, it's no longer optional.

Interview Questions

What's the real limitation of cfspreadsheet's update action?

It can only add a new sheet to an existing file, it cannot modify a sheet that's already there.

Why would cfspreadsheet-based code fail entirely on Lucee?

The tag isn't supported by Lucee at all. Lucee offers a native SpreadSheetNew() function and points toward community extensions instead of a built-in tag equivalent.

What changed about cfspreadsheet's password attribute in ColdFusion 2025?

It became mandatory for the write and update actions, previously optional code needs an explicit password value to keep working.

Summary

In this lesson, you read an Excel file into a query, built and wrote a spreadsheet object with spreadsheetNew()/spreadsheetAddRows(), covered update's real limitation to adding sheets only, the ColdFusion 2025 password requirement, and why cfspreadsheet has no native Lucee equivalent.

What's Next?

The next lesson covers cfchart, generating charts and graphs directly from a query.