IndexError: At least one sheet must be visible

Question:

 def multiple_dfs(sheet, row=2):

    writer = pd.ExcelWriter("testing.xlsx", engine='openpyxl')

    f1 = {
        'user': ['Bob', 'Jane', 'Alice'], 
        'income': [40000, 50000, 42000],
    }

    f2 = {
        'amount': ['Chest', 'Bras', 'Braa'], 
        'income': [40000, 50000, 42000]
    }

    frames = [f1, f2]


    for f in frames:
        try:
            wb = load_workbook("testing.xlsx")
            ws = wb.get_sheet_by_name("aaa")

            writer.wb = wb
            writer.sheets = dict((ws.title, ws) for ws in wb.worksheets)

            row = ws.max_row + 2
        except:
            pass 

        df = pd.DataFrame(f)
        df.to_excel(writer, sheet, startrow=row, index=False)
        writer.save()
    # writer.close()

multiple_dfs('aaa')

I got this error, but I can’t fix it. I adapt this short representation of what is happening in my code, but it is hard to see where is the real problem. Here is the

Traceback (most recent call last):
  File "create_and_update_xlsx_sheets.py", line 144, in <module>
    create_and_update_worksheets()
  File "create_and_update_xlsx_sheets.py", line 140, in create_and_update_worksheets
    writer.save()
  File "/home/jeremie/.virtualenvs/NHL/lib/python3.5/site-packages/pandas/io/excel.py", line 824, in save
    return self.book.save(self.path)
  ...
  File "/home/jeremie/.virtualenvs/NHL/lib/python3.5/site-packages/openpyxl/writer/workbook.py", line 61, in get_active_sheet
    raise IndexError("At least one sheet must be visible")
IndexError: At least one sheet must be visible

How could I fix that issue?

P.S. Be aware that error is displayed half the time.

Asked By: user8802531

||

Answers:

It seems like what you want to do is just write each DataFrame to the same sheet (appending it below the last), so I think you can write this as:

start_row = 1
for df in frames:  # assuming they're already DataFrames
    df.to_excel(writer, sheet, startrow=start_row, index=False)
    start_row += len(df) + 1  # add a row for the column header?
writer.save()  # we only need to save to disk at the very end!
Answered By: Andy Hayden

Alternatively, if you don’t need to load a workbook, you can merely use xlsxwriter instead of openpyxl; it hasn’t this problem. You can also create a workbook with the regular

from openpyxl import Workbook
#...
wb= Workbook()
ws=wb.active
with pd.ExcelWriter(output_filepath, engine="openpyxl") as writer:
    writer.book=wb
    writer.sheets = dict((ws.title, ws) for ws in wb.worksheets)
    #useful code
    df.to_excel(writer, sheet, ...)
    writer.save()

now you can work with both pandas.to_excel and the interesting methods of openpyxl that are not translated into it (that’s not my hack; found it here but can’t find where)

Answered By: Ando Jurai

working perfectly fine on pandas 1.1.5 and openpyxl 3.0.5.

Change your pandas and openpyxl library on above mentioned version.

Answered By: D Shah

In Pandas 1.3.5 I needed to assign the engine as xlsxwriter.

with pd.ExcelWriter('path-to-.xlsx-file',engine='xlsxwriter') as writer:     
    df.to_excel(writer, 'spreadsheet-name')

https://pandas.pydata.org/docs/dev/reference/api/pandas.ExcelWriter.html

Answered By: oldstudent

Same error, IndexError: At least one sheet must be visible, consistently reproduced when a writer is created, then saved, without having written anything. Example:

writer = pd.ExcelWriter(file_name, engine='openpyxl')
writer.save()

Stepping through the code, the workbook doesn’t contain any sheets at time of writing, visible or otherwise, despite having sheets before calling save.

Granted, hard to match that to your code, but a clue to you or next dev coming across same error.

Answered By: corolla

You should be able to do wb.save("filename.xlsx") rather than use excelwriter at all.

writer.save is an excelwriter method while openpyxl has its own save method that takes a filename after you opened a workbook.

You can also use the wb.sheetnames and wb.create_sheet to navigate sheets.

from openpyxl import Workbook, load_workbook
from openpyxl.utils.dataframe import dataframe_to_rows

wb = load_workbook(PATH + "yourfile.xlsx")
#writer = pd.ExcelWriter(PATH + "yourfile.xlsx", engine='openpyxl')

wb2 = []

if "MySheetName" in wb.sheetnames:
     wb2 = wb["MySheetName"]
else:
     wb2 = wb.create_sheet("MySheetName",-1)  #Auto add at the end

#wb2 is now the active sheet for wb

for r in dataframe_to_rows(df, index=True, header=True):
     wb2.append(r)

wb.save(PATH + "yourfile.xlsx")

Hope it helps

Answered By: Riaan Steenberg
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.