In Excel a user can select a range and hit Ctrl+Shift+L to show filters. I am trying to get equivalent behavior from an Office.js Add-in.
The closest I have come to that is adding a table over the range I want to filter and then adding a filter to the table. There seem to be a couple of significant problems with that however.
First, adding a table this way for 30000+ rows is very slow and I am frequently using tables much larger than that. If I do Ctrl+Shift+L over a range that size it is instantaneous.
Additionally, when I add the table, Office.js stylizes the range. I do not want any new styling for the range I just want a filter added.
My current code looks like this:
await Excel.run(async ctx => {
const table = await getOrCreateDataTable(ctx, "CostData", new ExcelRange(this.stateService.headerRow)); //see below
const validationColumn: Excel.TableColumn = table.columns.getItemOrNullObject("Validation");
validationColumn.filter.applyCustomFilter(`*${searchString}*`)
await ctx.sync();
});
export const getOrCreateDataTable = async(ctx: Excel.RequestContext, tableName: string, headerRow: ExcelRange): Promise < Excel.Table > => {
let table: Excel.Table = ctx.workbook.tables.getItemOrNullObject(tableName)
await ctx.sync();
if (!table.isNullObject)
console.log(`Table: ${tableName} found`)
else {
const sheet = await getSheet(ctx, headerRow.sheet)
const headerRange = sheet.getRange(headerRow.getRange()).getEntireRow().getUsedRange()
const usedRange: Excel.Range = sheet.getUsedRange()
const tableRange = headerRange.getBoundingRect(usedRange.getLastCell())
table = ctx.workbook.tables.add(tableRange, true)
table.name = tableName
await ctx.sync();
}
return table;
}