XLSX.jl
repository·master·Indexed 43 days ago
https://github.com/juliadata/xlsx.jlA Julia package for reading and writing Excel (.xlsx) spreadsheet files implementing the ECMA-376 standard. It provides comprehensive tools for managing worksheets, cell formatting, formulas, and Excel Tables (ListObjects), as well as support for charts, images, and defined names. The package integrates with FileIO.jl for generic loading and saving and requires Julia v1.10 (LTS) or more recent.
What's inside XLSX.jl
- XLSX.jl is a Julia package designed for reading and writing Excel spreadsheet files. It follows the ECMA-376 standard, which defines the XML structures contained within the Zip-compressed XLSX file format.
How Excel cell formatting hierarchy works
masterIn XLSX.jl, formatting follows the Excel
stylehierarchy. ACellrefers to aStyle, which definesAlignmentand can point to shared definitions forfont,fill,border, and numberformat. Multiple styles can share the same font or fill definition to optimize the file structure.`Cell` │ `Style` => `Alignment` │ ┌──────────┬────┴─────┬─────────┐ │ │ │ │ `font` `fill` `border` `format`Use ReferencedFormula for ranges
masterWhen you provide a contiguous range to
setFormula(e.g.,setFormula(s, "B2:B4", "=B1+A2")),XLSX.jlcreates aReferencedFormula.This behaves like Excel's 'drag fill' feature: the first cell in the range contains the actual formula, and subsequent cells contain a reference to that first cell with appropriate offsets. When calling
XLSX.getFormulaon any cell within that range, the returned string will be the adjusted formula as it would appear in the Excel formula bar.s[1:4, 1] = 1:4 setFormula(s, "B1", "=A1") setFormula(s, "B2:B4", "=B1+A2") # creates a running total XLSX.getFormula(s, "B2") # returns "=B1+A2" XLSX.getFormula(s, "B4") # returns "=B3+A4" (adjusted for offset)Handle relative and absolute cell references in formulas and values
masterWhen specifying
value,value2, orformula(for:expressiontypes), you can use relative or absolute references.Important: In Julia, the
$character used for absolute references in Excel must be escaped with a backslash (\$).- Relative Reference:
"B2"— The cell used in comparison is adjusted for each cell in the target range (e.g., if the range starts at A2, A2 compares to B2, A3 compares to B3, etc.). - Absolute Reference:
"\$B\$2"— Every cell in the target range is compared against the exact same cell (B2).
Limitations:
- Relative cell references cannot be used with
:dataBar,:colorScale, or:iconSettypes. - References to cells in other sheets (e.g.,
"OtherSheet!A1") are not yet universally implemented in XLSX.jl.
# Relative reference value = "B2" # Escaped absolute reference value = "\$B\$2"- Relative Reference:
Overlay multiple conditional formats
masterYou can apply multiple conditional formats to the same cell or overlapping ranges. Excel applies these in priority order, which corresponds to the order in which they were defined using
setConditionalFormat.To check the current formats applied to a worksheet, use
XLSX.getConditionalFormats(s).# Applying multiple formats sequentially XLSX.setConditionalFormat(s, "A2:C5", :colorScale; colorscale="greenyellowred") XLSX.setConditionalFormat(s, "A2:C5", :top10; operator ="topN", value="3", font=["color"=>"magenta3", "strike"=>"true"], fill=["pattern"=>"lightVertical", "fgColor"=>"lawngreen", "bgColor"=>"cornsilk"], border=["style"=>"double", "color"=>"cyan"]) XLSX.setConditionalFormat(s, "A2:A5", :cellIs; operator="lessThan", value="2", font=["color"=>"coral", "bold"=>"true"], fill=["pattern"=>"lightHorizontal", "fgColor"=>"cornsilk"], border=["style"=>"dashed", "color"=>"orangered4"])How Tables.jl integration works in XLSX.jl
masterXLSX.jl is built on the
Tables.jlinterface, allowing seamless interoperability with other Julia data packages.Key Concepts:
- Writing:
XLSX.writetableandXLSX.XLSXFileaccept any object conforming to theTables.jlinterface (e.g.,DataFrames.DataFrame). - Reading: You can convert an Excel worksheet back into a
Tables.jlcompatible format usingXLSX.eachtablerow(sheet). This returns anXLSX.TableRowIterator. - Sinks:
XLSXFilecan act as a sink for functions likeCSV.read, allowing you to pipe CSV data directly into an Excel file.
Example: Reading a worksheet into a DataFrame
using XLSX, DataFrames f = XLSX.readxlsx("output_table.xlsx") s = f["report"] df2 = XLSX.eachtablerow(s) |> DataFrames.DataFrameusing CSV, XLSX # Direct pipe from CSV to XLSX xf = CSV.read("iris.csv", XLSXFile)- Writing:
Update rich text cells with setFont, setUniformFont, or setUniformStyle
masterFunctions like
setFont,setUniformFont, andsetUniformStyleoperate at the cell level. When applied to a cell containing rich text:- Partial Overrides: If you use
setFontto change an attribute (e.g.,under="none"), it will remove that specific attribute from the rich text runs, but other heterogeneous formatting (like color or size) will remain. - Uniformity:
setUniformFontandsetUniformStylewill convert rich text attributes into uniform cell-level attributes if they match the new setting. Any remaining heterogeneity that doesn't match the new uniform setting will be preserved. - Limitations: These functions cannot target specific substrings. To edit individual runs, you must overwrite the cell with a completely new
RichTextStringorAnnotatedString.
Note: An
XLSXFilemust be opened in write mode to edit rich text formatting.# Removing underlining from a rich text cell in column B setFont(s, "B"; under="none") # Applying a uniform color to a range; existing rich text heterogeneity remains setUniformFont(s, "A1:F2"; color="orange") # Applying the style of A1 to a range; rich text heterogeneity (like bold/italic) is preserved setUniformStyle(s, "A1,D1:F2")- Partial Overrides: If you use
Distinguish between tabular data and native Excel Tables
masterIn XLSX.jl, the term 'table' refers to two different concepts:
- Tabular data in a cell range: A rectangular block of cells that looks like a table. Its extent is inferred heuristically from cell content using functions like
XLSX.gettable,XLSX.readtable, orXLSX.eachtablerow(sheet, ...). This is not a formal object in the Excel file. - A native Excel Table: A formal object created in Excel (via Insert → Table or
Ctrl+T). It is represented by theXLSX.Tabletype. It has a unique name, a recorded extent (range), named columns, and may include styles, autofilters, or a totals row. Because its extent is recorded in the file, XLSX.jl does not need to guess its boundaries.
When using ambiguous function names, the argument type determines the behavior:
gettable(sheet)reads an inferred range, whilegettable(t::Table)reads a native Excel Table object.- Tabular data in a cell range: A rectangular block of cells that looks like a table. Its extent is inferred heuristically from cell content using functions like
Difference between static and dynamic conditional formats
masterXLSX.jl supports two ways to handle conditional formatting, which behave differently when cell values change:
Static conditional formats: These are applied based on the cell values at the exact moment the formatting function is run. If the cell values change later, the formatting will not update automatically. These are created using
setAttribute()functions (likeXLSX.setFont,XLSX.setFill, orXLSX.setBorder).Dynamic conditional formats: These use Excel's native conditional formatting engine. If the cell values change, the formatting will update automatically to reflect the new values. These are created using the
setConditionalFormat()function.
How splitFreeze panes work
masterThe
splitFreeze()function behaves identically tofreezePanes()in terms of visual result. However, it marks the panes internally withstate="frozenSplit". This mimics Excel's behavior when a user freezes panes that were originally created via a draggable split. This distinction only affects how Excel handles the panes if the user later interacts with them (e.g., unfreezing them) within Excel.using XLSX f = XLSX.newxlsx() sheet = f[1] # Freezes panes and marks them as originating from a split XLSX.splitFreeze(sheet; nrows=3, ncols=2)Apply uniform attributes vs uniform styles
masterXLSX.jl provides different ways to apply formatting to ranges, depending on whether you want to merge attributes or overwrite them entirely.
1.
setAttribute(e.g.,setFont,setBorder)Behavior: Merges new attributes with existing ones on a cell-by-cell basis. Use case: When you want to add a border to cells without losing their existing background colors or fonts.
2.
setUniformAttribute(e.g.,setUniformBorder,setUniformFill)Behavior: Updates the first cell in the range with the new attribute, then applies that specific attribute ID to all other cells in the range. This overwrites only that specific category (e.g., only the border) for the rest of the cells. Use case: When you want all cells in a range to have the same border, but keep their existing fonts/fills.
3.
setUniformStyleBehavior: Takes the
styleIdof the first cell in the range and applies it uniformly to every cell in the range. This overwrites all formatting (font, fill, border, format, and alignment) to ensure perfect consistency. Use case: When you need a range of cells to be completely identical in appearance. This is the most efficient method for large ranges.# 1. Merge (cell-by-cell) XLSX.setBorder(s, "B2,D2,F2"; top=["style"=>"thick", "color"=>"red"]) # 2. Uniform category (overwrites only borders) XLSX.setUniformBorder(s, "B2,D2,F2"; allsides=["color"=>"green"]) # 3. Uniform everything (overwrites all formatting) XLSX.setUniformStyle(s, "B2,D2,F2")Manage Defined Names and Scopes
masterDefined names in Excel have two scopes: Workbook scope (visible throughout the entire file) and Worksheet scope (visible only within a specific sheet).
Functions in XLSX.jl determine their scope based on the first argument provided:
- Passing an
XLSXFileobject targets workbook scope. - Passing a
Worksheetobject targets that specific worksheet scope.
Key behaviors:
XLSX.getDefinedNames(ws)returns only names scoped to that worksheet. To see all names in the file regardless of scope, useXLSX.getAllDefinedNames(file).- Names are matched case-insensitively.
- Defined names share a namespace with Excel Table names.
API Operations:
XLSX.addDefinedName(...)to create a name.XLSX.getDefinedNames(...)to list names in a specific scope.XLSX.getAllDefinedNames(file)to list all names in the workbook.XLSX.deleteDefinedName(...)to remove a name.XLSX.deleteAllDefinedNames(...)to clear names.
- Passing an