Openpyxl include a totalsrow that subtotals visible rows in Table - python-3.x

I am using openpyxl to create a Table. But I cannot figure out how to get the TotalsRow to appear and I cannot find any guidance through searching. Only the openpyxl documentation, which I cannot make sense of it. Here is the code I have:
LastRow = ws.max_row
tab = Table(displayName="Table10", ref="A1:CU198",
totalsRowShown=True)
style = TableStyleInfo(name="TableStyleMedium9", showFirstColumn=False,
showLastColumn=False, showRowStripes=False, showColumnStripes=True)
tblcolmn = TableColumn(id=1,name='TableTotals',totalsRowFunction='sum', totalsRowLabel='Totals')
tab.TableColumn = tblcolmn
tab.tableStyleInfo = style
ws.add_table(tab)
But it does not show the TotalsRow, so I cannot figure out what I am doing wrong. Oh, and I cannot calculate the sums in python, becuase I need the sum formula to change when I filter the Table.
I appreciate any help!

I couldn't figure out the solution with Openpyxl, but I did find the solution with xlsxwriter using the below code. Hope this helps someone:
ColDict = [{'header': DFColumnHeadersList,'total_string':'Totals','total_function':'sum' } for ColList in df.columns]
wb = xlsxwriter.Workbook(PathFileName)
ws = wb.add_worksheet('Sheet1')
ws.add_table(0,0,198,99,{'data': TestFileList, 'total_row': True, 'columns': ColDict,'last_column': False, 'banded_columns': True, 'name':'Table10'})
wb.close()

Related

How to keep the manual formatting of googlesheet while writing data using python

spreadsheet = client.open_by_key(sheet_id)
worksheet = spreadsheet.worksheet_by_title(worksheet_name)
worksheet.set_dataframe(res_df, copy_head = False, start = res_df_index)
I am writing a array of data in one of the columns in googlesheet. However doing so, I am losing the manual formatting I had applied in google sheet
Can someone please help me with this ?

Selecting multiple fields in win32c.xlPageField

Objective: I'm using a python script to generate an excel report (contains lots of pivot tables).
Problem: Unable to figure out how to add multiple items to pivot table filter
I've figured out a cumbersome solution where I can create individual data sets that are pre-filtered so I don't need to filter them in the pivot table. However, this isn't really efficient or effective if somebody wants to swap the filter on the final excel report.
I'll use code I found online as an example:
import win32com.client
Excel = win32com.client.gencache.EnsureDispatch('Excel.Application')
win32c = win32com.client.constants
wb = Excel.Workbooks.Add()
Sheet1 = wb.Worksheets("Sheet1")
TestData = [['Country','Name','Gender','Sign','Amount'],
['CH','Max' ,'M','Plus',123.4567],
['FR','Max' ,'M','Minus',-23.4567],
['CH','Max' ,'M','Plus',12.2314],
['SP','Max' ,'M','Minus',-2.2314],
['CH','Sam' ,'M','Plus',453.7685],
['CH','Sam' ,'M','Minus',-53.7685],
['CH','Sara','F','Plus',777.666],
['CH','Sara','F','Minus',-77.666],
['DE','Hans','M','Plus',345.088],
['DE','Hans','M','Minus',-45.088],
['DE','Paul','M','Plus',222.455],
['DE','Paul','M','Minus',-22.455]]
for i, TestDataRow in enumerate(TestData):
for j, TestDataItem in enumerate(TestDataRow):
Sheet1.Cells(i+2,j+4).Value = TestDataItem
cl1 = Sheet1.Cells(2,4)
cl2 = Sheet1.Cells(2+len(TestData)-1,4+len(TestData[0])-1)
PivotSourceRange = Sheet1.Range(cl1,cl2)
PivotSourceRange.Select()
wb.Worksheets.Add()
Sheet2 = wb.Worksheets("Sheet2")
cl3=Sheet2.Cells(4,1)
PivotTargetRange= Sheet2.Range(cl3,cl3)
PivotTableName = 'ReportPivotTable'
PivotCache = wb.PivotCaches().Create(SourceType=win32c.xlDatabase, SourceData=PivotSourceRange, Version=win32c.xlPivotTableVersion14)
PivotTable = PivotCache.CreatePivotTable(TableDestination=PivotTargetRange, TableName=PivotTableName, DefaultVersion=win32c.xlPivotTableVersion14)
PivotTable.PivotFields('Name').Orientation = win32c.xlRowField
PivotTable.PivotFields('Country').Orientation = win32c.xlPageField
PivotTable.PivotFields('Country').CurrentPage = 'SP'
PivotTable.PivotFields('Gender').Orientation = win32c.xlColumnField
PivotTable.PivotFields('Sign').Orientation = win32c.xlColumnField
DataField = PivotTable.AddDataField(PivotTable.PivotFields('Amount'))
Excel.Visible = 1
wb.SaveAs('ranges_and_offsets.xlsx')
Excel.Application.Quit()
This generates a pivot table in excel and sets the Country Filter to SP. I know adding the following line will enable the multi selection option.
PivotTable.PivotFields('Country').EnableMultiplePageItems = True
At this point, I'm stuck. I would like to find a way to set Country to both SP and DE. I feel like the correct way to do this is to switch .CurrentPage to .CurrentPageList
However, I can't seem to get .CurrentPageList to work
Any help would be highly appreciated!
this maybe too late for this post, but the way I solved this was creating two loops
PivotTable.PivotFields(target_column).Position = some_position
PivotTable.PivotFields(target_column).EnableMultiplePageItems = True
for item in show_values:
PivotTable.PivotFields(target_column).PivotItems(item).Visible = True
for item in excl_values:
PivotTable.PivotFields(target_column).PivotItems(item).Visible = False
I hope it helps!

convert output formula to value?

I need to convert function fun(=SUMIF(B1:B16,B2,C1:C16)) into value so that I can use the output in another operation.
Moreover, I need to know which is the best module for working in excel and formatting cells.
import openpyxl
wb = openpyxl.load_workbook('file.xlsx')
ws = wb.active
# add a simple formula
ws['A3'] = ("=SUMIF(B1:B16,B2,C1:C16)")
wb.save("file.xlsx")
You could have a look at pyparsing, but I don't know, if it suits your needs best and can solve the given task.

Creating an Excel Table with MATLAB

Since writing varying sized data ranges to a sheet seems to remove an Excel Table if the data range is larger than the existing Excel tables range, I want to create a Table in Excel every time I run the code. I'm currently having a fair bit of difficulty creating the tables. The code I have right now to try and create the ListObject:
eSheets = e.ActiveWorkbook.Sheets;
eSheet = eSheets.get('Item', j);
eSheet.Activate;
eSheet.Range(horzcat('A1:R',mat2str(size(obj,1)+1))).Select;
eSheet.Listobjects.Add;
eSheet.Listobjects.Item(1).TableStyle = 'TableStyleMedium2';
eSheet.ListObjects.Item(1).Name = tablename;
Any commentary or suggestions would be appreciated
I dont know about using eSheet in matlab but with the function
xlswrite(filename,A,sheet,xlRange)
you can also write your data from a matrix to an excel table http://de.mathworks.com/help/matlab/ref/xlswrite.html and with
[A,B] = xlsfinfo('foofoo.xlsx');
sheetValid = any(strcmp(B, 'foo2'));
you can also check if a table sheet already exist so that you wont override the old one and create a new one, as seen in https://de.mathworks.com/matlabcentral/answers/25848-how-to-check-existence-of-worksheet-in-excel-file
I am not sure if this is what you are looking for thougth
Alright, since the post got downvoted (not sure why...) I found my own answer with the help of some VBA forums and MATLAB Newsgroup. Here's what the final code looks like for anyone else that has issues:
e = actxserver('Excel.Application');
ewb = e.Workbooks.Open('Path/to/file');
eSheets = e.ActiveWorkbook.Sheets;
eSheet = eSheets.get('Item', j);
eSheet.Activate;
range = horzcat('A1:R',mat2str(size(obj,1)+1));
range_todelete = horzcat('A1:R',mat2str(size(obj,1)+300));
Range1 = eSheet.get('Range',range_todelete);
Range1.Value=[];
eSheet.Range(range).Select;
name = 'Table_Name';
try eSheet.ListObjects(name).Item(1).Delete
catch
end
eSheet.Listobjects.Add;
eSheet.ListObjects.Item(1).Name = name;
eSheet.ListObjects.Item(1).TableStyle = 'TableStyleMedium2';
Range = eSheet.get('Range',range);
Range.Value = cellarray;

Importing a list from excel, but having trouble splitting it into 4 columns

I know this is very basic, but I have been using Python for 2 weeks now and banging my head against the wall trying to fix this. I have checked almost every single thread in here and tried to make sense of the Python 2.7 documentation and also researched whatever excerpts from Programming with Win32 by Hammod I could find.
Below is a section of my code. I am pulling in a named range from excel into a Python Gui. The data comes into row=4, column=1 as I coded it. The problem is I need to parse this named range so that the range (which is four float points) is split amongst row=4 clomuns 1,2,3,4. I know this is basic. I wouldnt have posted if I could find the answer anywhere else. If someone could just point me in the right direction i would really appreciate it.
xl = win32com.client.Dispatch('excel.application')
wbs = xl.Workbooks
wb = wbs.Open('C:\Users\Owner\Desktop\AutoPrime.xls')
xl.visible = 1
xlSheet = xl.Sheets(1)
xlSheet.Range('Fronts').Value
#Frame
Ftreas = Frame(F, relief="groove", border=2)
Ftreas.pack(side="left")
lp2a = Label(Ftreas, text=xl.ActiveSheet.Range('Fronts').Value, justify='center')
lp2a.grid(row=4,column=1, sticky='EW')
While I have not worked with Phyton before, I know that your line xlSheet.Range('Fronts') will return a Range object. You can access individual cells of a Range object with the default property, e.g.:
rng = xlSheet.Range('Fronts')
val1 = rng(1, 1).Value
val2 = rng(2, 1).Value //this returns the cell in row 2/column 1 of the range
arr = rng.Cells //this will return a 4x1 array of values

Resources