How to cancel auto filter on table with openpyxl - python-3.x

The title said it all :)
But still, I'm using the class Table from openpyxl.worksheet.table to define a table in excel file which I create. My problem is that the table that is created has Filter on the first row that I want to remove (from the script, not by opening the Excel file).
This is the calling for Table class:
tab = Table(displayName='Table_{}'.format(table_name.replace(' ', '_')),
ref="{}:{}".format(table_start, table_end))
This is what I get:
This is what I want to get:
I search for it at OpenPyXL Docs but find only adding that filtering...
There is any way to remove this?
Many thanks!

wb = load_workbook(filename="data.xlsx")
ws = wb["Sheet1"]
ws.auto_filter.ref = None
for i in range(2, ws.max_row + 1):
ws.row_dimensions[i].hidden = False
wb.save("data.xlsx")

I just ran across this and here is how I solved it.
#Opens the file
wb = load_workbook(filename = 'somefile')
#Set worksheet
ws = wb['sheetname'] # Tab name
#set table
tbl = ws.tables["tablename"]
#removes all filters
tbl.autoFilter.filterColumn.clear()

helo,
tab = Table( displayName='Table_{}'.format(table_name.replace(' ', '_'))
, ref="{}:{}".format(table_start, table_end)
, headerRowCount = 0 # default is 1
)

Related

Case insensitive search of an Excel file using Pandas read_excel

I need to get sheets from an Excel file with a certain name. Unfortunately sometimes the sheet names are not formatted correctly ie "Test Sheet" vs "Test sheet". I need a case insestive way of getting these sheets.
excel_file= pd.ExcelFile("file_name.xlsx")
sheet_needed = pd.read_excel(excel_file, sheet_name="Test Sheet") # <- This needs to be case insensitive
So pandas doesnt seem to have a good way of having a case insensitive search, However you can get the sheetnames as a list and pd.read will accept an index for the sheet name so I came up with this to solve the problem
excel_file= pd.ExcelFile("file_name.xlsx")
sheet_to_find = "Test Sheet"
# Get all the sheetnames as a list
sheet_names = excel_file.sheet_names
# Format the list of sheet names
sheet_names = [name.lower() for name in sheet_names]
# Get the index that matches our sheet to find
index = sheet_names.index(sheet_to_find.lower())
# Feed this index into pandas
sheet_needed = pd.read_excel(excel_file, sheet_name=index)
I don't know how to make that request case insesitive, but you could try to manipulate the file with openpyxl something like this:
import openpyxl
filename = 'file_name.xlsx'
wb = openpyxl.load_workbook(filename)
for ws in wb.worksheets:
ws.title = ws.title.title()
filename = 'new_'+filename
wb.save(filename)
wb.close()
the old title gets replaced with the 'titlelized' name of itself. You could also use the lower() or upper() function of the str object for that.

Openpyxl created excel file with table causes file that requires recovery error

I have been testing adding a table to a worksheet using openpyxl, but I get the error below when I try to open it. The file opens, but the formatting isn't correct. After hitting recover, excel reports that there was an issue with the table xml. Is there a workaround/fix for this?
The code I'm using:
import openpyxl
from openpyxl import Workbook
from openpyxl.worksheet.table import Table, TableStyleInfo
xl_file_name = "new_test.xlsx"
wb = Workbook()
ws = wb.worksheets[0]
ws.title = "Table_Sheet"
headers = ["header1","header2","header3"]
for col in range(1,len(headers)+1):
for row in range(1,5):
if row == 1:
ws.cell(row,col).value = headers[col-1]
else:
ws.cell(row,col).value = str(row)
tbl = Table(displayName="Tbl1",ref="A1:C4")
style = TableStyleInfo(name="TableStyleMedium9", showFirstColumn=False, showLastColumn=False, showRowStripes=True, showColumnStripes=True)
tbl.tableStyleInfo = style
ws.add_table(tbl)
wb.save("new_test.xlsx")
Your name for the table is causing the problem. Run the same code with displayName="Tbl" or displayName="Tbl_1" instead, and you'll see it works fine. I'm not 100% sure, but I think the cause of the issue is that the name you give conflicts with the formatting for a possible cell reference of TBL1.
For me the following worked:
Change the Workbook as you wish (only Data no formatting)
Save the Workbook (If you would try to open it here it will display the error message)
Close the Workbook
Open the Workbook again (I think here Excel fixes the issue automatically)
Insert necessary formatting commands
Save the workbook
Close the Workbook
Or, as code:
import openpyxl
workbook = openpyxl.load_workbook(Source_Path)
##your code appending and deleting values - which I think sometimes causes the errors
workbook.save(Destination_Path)
workbook.close
#Now open it again
workbook = openpyxl.load_workbook(Destination_Path)
#Your Code to format
workbook.save(Destination_Path)
workbook.close
Now you should be able to open the Excel file without an error.
I've had the same error message.
I was creating tables with numbers at the start of the name, so I changed that code to add t_ at the beginning, so
table_name = "112MHZ_data"
became
table_name = "t_112MHZ_data"
And that solved it for me.

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!

How to add Calculated Member to Pivot Table via Python win32

I'm trying to add a calculated column into this pivot table that is being generated via a python script with import win32com.client.
Code is posted below that is generating the pivot table. I'm not sure how to add a column. In VBA it would be wb.PivotTable.CalculatedField.Add but that didn't work (at least the syntax I tried).
I'm trying to calculate [OoCUnits] / [GrossUnits]
#Make Pivot version with four weeks data
Excel = win32com.client.gencache.EnsureDispatch('Excel.Application')
win32c = win32com.client.constants
wb = Excel.Workbooks.Open(filename)
ws3 = wb.Worksheets('Dataset')
cl1 = ws3.Cells(1,1)
cl2 = ws3.Cells(max_row,max_col)
PivotSourceRange = ws3.Range(cl1,cl2)
ws3.Activate()
PivotSourceRange.Select()
wb.Sheets.Add (After=wb.Sheets(3))
ws4 = wb.Worksheets(4)
ws4.Name = 'Pivot'
cl3 = ws4.Cells(4,1)
PivotTargetRange = ws4.Range(cl3,cl3)
PivotTableName = 'OoCPivot'
#Make Pivot Table
PivotCache = wb.PivotCaches().Create(SourceType=win32c.xlDatabase, SourceData=PivotSourceRange, Version=win32c.xlPivotTableVersion14)
PivotTable = PivotCache.CreatePivotTable(TableDestination=PivotTargetRange, TableName=PivotTableName, DefaultVersion=win32c.xlPivotTableVersion14)
PivotTable.PivotFields('Product Name').Orientation = win32c.xlRowField
PivotTable.PivotFields('Product Name').Position = 1
PivotTable.PivotFields('Customer Number').Orientation = win32c.xlPageField
PivotTable.PivotFields('Customer Number').Position = 1
PivotTable.PivotFields('Customer Name').Orientation = win32c.xlPageField
PivotTable.PivotFields('Customer Name').Position = 2
PivotTable.PivotFields('Week Ending Date').Orientation = win32c.xlColumnField
PivotTable.PivotFields('Week Ending Date').Position = 1
DataField = PivotTable.AddDataField(PivotTable.PivotFields('GrossUnits'))
DataField.NumberFormat = '#0.00'
DataField = PivotTable.AddDataField(PivotTable.PivotFields('OoCUnits'))
DataField.NumberFormat = '#0.00'
I'm inserting the values with the DataField. The script is not presenting any issues as is.
EDIT: The exact code I implemented to solve. The last two lines are just formatting. I'm including in case it helps someone else.
CalcField = PivotTable.CalculatedFields().Add('OoC Unit %','= OoCUnits / GrossUnits')
DataField = PivotTable.AddDataField(PivotTable.PivotFields('OoC Unit %'))
DataField.NumberFormat = '#%'
PivotTable.DisplayErrorString = True
Actually, the method is PivotTable.CalculatedFields().Add() according to docs. Consider placing below at bottom:
CalcField = PivotTable.CalculatedFields().Add("OC_GrossPct", "= OoCUnits / GrossUnits")
PivotTable.PivotFields("OC_GrossPct").Orientation = win32c.xlDataField

How to insert data into excel in Horizontal?

import xlwt
wb = xlwt.Workbook(encoding='utf-8')
ws = wb.add_sheet('Sheet1', cell_overwrite_ok=True)
data = (
[(1,),(2,),(3,)],
[('a',),('b',),('c',)],
[('e',),('f',),('g',)],
)
for index, value in enumerate(data):
for r_num, r_value in enumerate(value):
ws.write(r_num, index,r_value[0])
wb.save('test.xls')
My result is as below. But how can I insert mydata into excel in Horizontal?
If I understand you question the right way, you want the numbers to be in the top row. If so, you can just replace ws.write(r_num, index,r_value[0]) with ws.write(index, r_num,r_value[0]).

Resources