Search code examples
pythonpandasxlsxwriter

writing image to excel with xlsxwriter returns " workbook not callable"


Using the first answer to the following link Python: Writing Images and dataframes to the same excel file as a guide:

I have the following script in which I like to write a dataframe object to one sheet and a bunch of images to another sheet.

class name():

 def some_func(self):
     self.writer = pd.ExcelWriter('Name1',engine='xlsxwriter')
     return
 
 def write_excel(self):
     self.df.to_excel(self.writer,sheet_name='Name',index=False, header=False)
     self.writer.save()   
    return

def write_excel(self):
    self.workbook = self.writer.book('Name1')
    self.worksheet = self.writer.sheets(name='images')
    images=[]
    do some stuff
    for i,image in enumerate(images):
        self.worksheet.insert_image('D1',0,y_postn[i],image)  
    self.writer.save()   
    return

It returns the following error

'Workbook' object is not callable

Not sure how to interpret this error or fix it?...


Solution

  • The error comes from this line:

    self.workbook = self.writer.book('Name1')
    

    Book is an object, not a method and it has the following fields (__call__ is not one of them):

    _Workbook__active_sheet
    _Workbook__all_fonts_num_formats_xf_styles_rec
    _Workbook__all_links_rec
    _Workbook__backup_on_save
    _Workbook__backup_rec
    _Workbook__bof_rec
    _Workbook__bookbool_rec
    _Workbook__boundsheets_rec
    _Workbook__codepage_rec
    _Workbook__country_code
    _Workbook__country_rec
    _Workbook__custom_palette_b8
    _Workbook__datemode_rec
    _Workbook__dates_1904
    _Workbook__dsf_rec
    _Workbook__eof_rec
    _Workbook__ext_sst_rec
    _Workbook__first_tab_index
    _Workbook__fngroupcount_rec
    _Workbook__height_twips
    _Workbook__hide_obj_rec
    _Workbook__hpos_twips
    _Workbook__hscroll_visible
    _Workbook__intf_end_rec
    _Workbook__intf_hdr_rec
    _Workbook__intf_mms_rec
    _Workbook__obj_protect
    _Workbook__obj_protect_rec
    _Workbook__owner
    _Workbook__palette_rec
    _Workbook__password_rec
    _Workbook__precision_rec
    _Workbook__prot4rev_pass_rec
    _Workbook__prot4rev_rec
    _Workbook__protect
    _Workbook__protect_rec
    _Workbook__refresh_all_rec
    _Workbook__selected_tabs
    _Workbook__sheet_refs
    _Workbook__sst
    _Workbook__sst_rec
    _Workbook__styles
    _Workbook__tab_width_twips
    _Workbook__tabid_rec
    _Workbook__tabs_visible
    _Workbook__use_cell_values
    _Workbook__useselfs_rec
    _Workbook__vpos_twips
    _Workbook__vscroll_visible
    _Workbook__width_twips
    _Workbook__window1_rec
    _Workbook__wnd_hidden
    _Workbook__wnd_mini
    _Workbook__wnd_protect
    _Workbook__wnd_protect_rec
    _Workbook__worksheet_idx_from_name
    _Workbook__worksheets
    _Workbook__write_access_rec
    __class__
    __delattr__
    __dict__
    __dir__
    __doc__
    __eq__
    __format__
    __ge__
    __getattribute__
    __gt__
    __hash__
    __init__
    __init_subclass__
    __le__
    __lt__
    __module__
    __ne__
    __new__
    __reduce__
    __reduce_ex__
    __repr__
    __setattr__
    __sizeof__
    __str__
    __subclasshook__
    __weakref__
    _get_supbook_index
    _ownbook_supbook_ref
    _ownbook_supbookx
    _supbook_xref
    _xcall_supbook_ref
    _xcall_supbookx
    _xcall_xref
    active_sheet
    add_font
    add_rt
    add_sheet
    add_sheet_reference
    add_str
    add_style
    backup_on_save
    convert_sheetindex
    country_code
    dates_1904
    default_style
    del_str
    encoding
    get_active_sheet
    get_backup_on_save
    get_biff_data
    get_country_code
    get_dates_1904
    get_default_style
    get_height
    get_hpos
    get_hscroll_visible
    get_obj_protect
    get_owner
    get_protect
    get_sheet
    get_style_stats
    get_tab_width
    get_tabs_visible
    get_use_cell_values
    get_vpos
    get_vscroll_visible
    get_width
    get_wnd_mini
    get_wnd_protect
    get_wnd_visible
    height
    hpos
    hscroll_visible
    obj_protect
    owner
    protect
    raise_bad_sheetname
    rt_index
    save
    set_active_sheet
    set_backup_on_save
    set_colour_RGB
    set_country_code
    set_dates_1904
    set_height
    set_hpos
    set_hscroll_visible
    set_obj_protect
    set_owner
    set_protect
    set_tab_width
    set_tabs_visible
    set_use_cell_values
    set_vpos
    set_vscroll_visible
    set_width
    set_wnd_mini
    set_wnd_protect
    set_wnd_visible
    setup_ownbook
    setup_xcall
    sheet_index
    str_index
    tab_width
    tabs_visible
    use_cell_values
    vpos
    vscroll_visible
    width
    wnd_mini
    wnd_protect
    wnd_visible
    

    Here's the official example for how to use this API:

    # Get the xlsxwriter objects from the dataframe writer object.
    workbook  = writer.book
    worksheet = writer.sheets['Sheet1']
    
    # Create a chart object.
    chart = workbook.add_chart({'type': 'column'})
    
    # Get the dimensions of the dataframe.
    (max_row, max_col) = df.shape
    
    # Configure the series of the chart from the dataframe data.
    chart.add_series({'values': ['Sheet1', 1, 1, max_row, 1]})
    
    # Insert the chart into the worksheet.
    worksheet.insert_chart(1, 3, chart)
    

    You are not supposed to call workbooks or sheets as if they are functions. You access functions within them such as .add_chart or .insert_chart.

    How do you get your hands on a spreadsheet with books and sheets in it in the first place? Like this:

    # Create a Pandas dataframe from the data.
    df = pd.DataFrame({'Data': [10, 20, 30, 20, 15, 30, 45]})
    
    # Create a Pandas Excel writer using XlsxWriter as the engine.
    writer = pd.ExcelWriter('pandas_simple.xlsx', engine='xlsxwriter')
    
    # Convert the dataframe to an XlsxWriter Excel object.
    df.to_excel(writer, sheet_name='Sheet1')
    
    # Get the xlsxwriter objects from the dataframe writer object.
    workbook  = writer.book
    worksheet = writer.sheets['Sheet1']
    

    You also have the option of accessing the xlswriter APIs directly without going through pandas (but I don't see why you would in your particular case):

    workbook  = xlsxwriter.Workbook('filename.xlsx')
    worksheet = workbook.add_worksheet()
    

    Have a look at the official documentation - it's full of clear examples.