sim
sim

Reputation: 1257

Creating and naming a table in xlwings

I am trying to use xlwings to interface Excel from some of my Python code and unfortunately only found stackoverflow threads or documentation on accessing/reformatting already existing Excel tables rather than creating new ones from scratch.

edit: solution added based on David Zemen's answer (additional getters and setters for ListObject properties are available here.

import xlwings

df = ... # initialising some pandas DataFrame

book = xlwings.Book()
ws = book.sheets.active
ws.range("A1").options(index=False).value = df

# TODO: Create table
# downside: does not seem to be possible to define multiple tables
#           within a Sheet (based on explicit ranges)
tbl = ea_sheet.api.ListObjects.Add(1) 


# TODO: Set the name/formatting of the table
tbl.DisplayName = "tabname"  # sets the tablename

I know that I can expand the range selection using ws.range("A1").expand('table') and know that I can use the .name property of ranges to define them as named range.

However, does xlwings provide any means to create a table from a range (similar to using Home - Format as Table in the Excel UI)?

Upvotes: 4

Views: 5753

Answers (1)

David Zemens
David Zemens

Reputation: 53663

I'm not sure if xlwings directly supports the creation of ListObjects, but since it exposes the api, you could try something like:

xlSrcRange = 1
xlYes = 1
ws.range("A1").options(index=False).value = df
tbl_range = ws.range("A1").expand('table')
ws.api.ListObjects.Add(xlSrcRange, tbl_range, xlListObjectHasHeaders=xlYes)

Unfortunately, this does not seem to work and fails silently.

import xlwings as xw
import pandas as pd
import numpy as np
# creating a dummy dataframe
data = np.array(np.random.randint(0,100,(3,4)))
columns = ['A','B','A','C']
index = ['Row 1', 'Row 2', 'Row 3']
frame = pd.DataFrame(data, index=index, columns=columns)
book = xw.Book()
ws = book.sheets.active
ws.range("A1").options(index=False).value = frame
tbl_range = ws.range("A1").expand('table')
ws.api.ListObjects.Add(1, tbl_range)  ## This line fails, but no error is raised. 

I suspect there is some problem passing the xlwings Range as the second parameter to the Add method.

I tried a few other things and if we omit the range argument, the ws.api call seems to work when I run it (with the caveat that the current ActiveCell/selection must be within the table area/used range):

ws.api.ListObjects.Add(1)

enter image description here

Finally, I was able to get it to work with the ListObjects.Add method but using the .api to pass a valid Excel range rather than an xlwings range:

ws.api.ListObjects.Add(1, ws.api.Range(tbl_range.address))

Upvotes: 7

Related Questions