# Using XLSX.jl to save DataFrames to multiple sheets

**URL:** <https://discourse.julialang.org/t/using-xlsx-jl-to-save-dataframes-to-multiple-sheets/69379>\
**Category:** General Usage\
**Tags:** package, dataframes, xlsx\
**Created:** [October 7, 2021, 4:49pm UTC](https://discourse.julialang.org/t/using-xlsx-jl-to-save-dataframes-to-multiple-sheets/69379 "2021-10-07T16:49:39Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![JackC](https://avatars.discourse-cdn.com/v4/letter/j/4af34b/32.png) [@JackC](https://discourse.julialang.org/u/JackC)\
**Post date:** [October 7, 2021, 4:49pm UTC](https://discourse.julialang.org/t/using-xlsx-jl-to-save-dataframes-to-multiple-sheets/69379/1 "2021-10-07T16:49:39Z")

</div>

I’ve been using XLSX.jl to save dataframes to an Excel workbook. I would like to save each DataFrame to a different sheet in the workbook. The documentation gives an example of such a case that works:

```julia
df1 = DataFrames.DataFrame(COL1=[10,20,30], COL2=["Fist", "Sec", "Third"])
df2 = DataFrames.DataFrame(AA=["aa", "bb"], AB=[10.1, 10.2])

XLSX.writetable("report.xlsx", REPORT_A=( collect(DataFrames.eachcol(df1)), DataFrames.names(df1) ), REPORT_B=( collect(DataFrames.eachcol(df2)), DataFrames.names(df2) ))

```

However, in my case the number of dataframes is variable and I would like to find a way to handle any number of dataframes instead of hardcoding them into the writetable call. For example, if I had an array or collection of dataframes, I would ideally be able to format that correctly into the writetable call or iterate over the workbook and add each dataframe to a new sheet. Does anybody know if something like this is doable in XLSX.jl?

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [October 7, 2021, 6:01pm UTC](https://discourse.julialang.org/t/using-xlsx-jl-to-save-dataframes-to-multiple-sheets/69379/2 "2021-10-07T18:01:07Z")

</div>

I didn’t read the XLSX.jl docs but if all you need to do is pass a list of keyword arguments containing the sheet names and dataframes, you can create a named tuple with something like:

```julia
sheets = (; zip(names, dataframes)...)

```

and then splat the named tuple in the function call:

```julia
XLSX.writetable("report.xlsx", sheets...)
```

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [October 7, 2021, 6:02pm UTC](https://discourse.julialang.org/t/using-xlsx-jl-to-save-dataframes-to-multiple-sheets/69379/3 "2021-10-07T18:02:43Z")

</div>

You don’t have to hardcode keyword arguments. You can make a namedtuple or a dict with symbols as keys and then splat that into the XLSX call as variable length keyword args.

```julia
d = Dict(
    :sheet1 => df1,
    :sheet2 => df2,
)

XLSX.writetable("name.xlsx"; d...)

```

The semicolon before `d` is important because otherwise the iterable is splatted as a number of positional arguments, not keywords.

---

<div class="post-metadata">

**Author:** ![JackC](https://avatars.discourse-cdn.com/v4/letter/j/4af34b/32.png) [@JackC](https://discourse.julialang.org/u/JackC)\
**Post date:** [October 7, 2021, 6:41pm UTC](https://discourse.julialang.org/t/using-xlsx-jl-to-save-dataframes-to-multiple-sheets/69379/4 "2021-10-07T18:41:40Z")

</div>

This worked! Thanks!

---

<div class="post-metadata">

**Author:** ![fdekerme](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fdekerme/32/43574_2.png) [@fdekerme](https://discourse.julialang.org/u/fdekerme)\
**Post date:** [March 4, 2024, 5:40pm UTC](https://discourse.julialang.org/t/using-xlsx-jl-to-save-dataframes-to-multiple-sheets/69379/5 "2024-03-04T17:40:44Z")

</div>

I would like to (re)open the discussion because the proposed solution no longer seems to work. I have the error  
`AbstractDataFrame is not iterable. Use eachrow(df) to get a row iterator or eachcol(df) to get a column iterator`

Here is an alternative solution which comes directly from the XLSX.jl documentation ([API Reference · XLSX.jl](https://felipenoris.github.io/XLSX.jl/dev/api/#XLSX.writetable)):  
`XLSX.writetable("name.xlsx", "sheet1" => df1, "sheet2" => df2)`

fdekerm
