A slicer is the friendly box of buttons that filters a pivot table or table with a click. It looks like a control — a piece of interface, not a piece of data. But to make those buttons appear instantly, Excel freezes a complete list of every distinct value in the field the slicer filters into a dedicated part, xl/slicerCaches/slicerCache1.xml, and records which of those values the author last had selected. That cached list includes the items the author filtered out — the regions, customers, cost centres, or product lines that never appear in the visible result — and it survives deleting the source rows, hiding the source sheet, and filtering the pivot down to a single line. This post walks through where the slicer layer lives, what the item cache and the selection state leak, how timelines store the same thing for dates, how the cache names pivot caches and tables that may no longer be visible, why Document Inspector ignores it entirely, and how to actually strip cached slicer data before a workbook leaves the perimeter.
When a user adds a slicer to a pivot table or a table, Excel writes two cooperating things. The first is the visible control: a xl/slicers/slicer1.xml part describing the box of buttons, its caption, its column count, and its style. The second is the part that makes the buttons real — a xl/slicerCaches/slicerCache1.xml part holding a frozen, deduplicated list of every distinct value the slicer can offer. The control points at the cache; the cache holds the data. A timeline — the date-range version of a slicer — works the same way, storing its cached range and selection in a timelineCache part of the same shape.
The cache exists for a sensible engineering reason. A slicer that had to rescan the entire source field every time the file opened — to discover which regions or customers exist and lay out a button for each — would be slow, and a slicer whose source had been filtered, moved, or hidden would have no list to draw. The cache makes the control instant and robust: Excel paints the buttons from the frozen list and only rebuilds it when the source is present and a refresh is triggered. The side effect is that every slicer carries a complete inventory of the distinct values in the field it filters — and that inventory does not shrink when the visible data does. This is the same frozen-copy pattern as the pivot cache and the chart cache, applied to a layer everyone thinks of as a button bar rather than a data store.
A slicer’s cache lists every distinct value in its field, not just the ones currently selected. Filter a pivot down to a single region and the slicer still carries the full roster of regions — the ones you excluded are sitting in slicerCache1.xml in plain text, one entry each, ready to read.
The cache part pairs a small amount of wiring with the thing that matters: a list of cached items. Each distinct value in the slicer’s field becomes an <i> element carrying the value in its n attribute, and a boolean s attribute recording whether that item is currently selected. The top of the part names the pivot cache or table the slicer is bound to. A single field with a handful of values looks like this:
// xl/slicerCaches/slicerCache1.xml — the full item list plus selection
<slicerCacheDefinition name="Slicer_Customer" sourceName="Customer">
<pivotTables><pivotTable tabId="3" name="DealPipeline"/></pivotTables>
<data><olap>
<levels><level sourceCaption="Customer">
<ranges><range>
<i n="Northeast Hospital Group" s="1"/>
<i n="Pinnacle Retail (at-risk)" s="0"/>
<i n="Project Falcon (confidential)" s="0"/>
<i n="Westbrook & Sons — DO NOT CONTACT" s="0"/>
</range></ranges>
</level></levels>
</olap></data>
</slicerCacheDefinition>
Two distinct things leak from this one part. The first is the full membership of the field: every customer the workbook has ever seen in that column, including the three the author filtered out. The visible pivot might show only Northeast Hospital Group, but the cache names Project Falcon (confidential) and Westbrook & Sons — DO NOT CONTACT in plain text. The second is the selection state: the s="1" / s="0" flags record exactly which items the author last had in view — a frozen snapshot of the analytical lens they were looking through when they saved.
A slicer cache is, in effect, a SELECT DISTINCT over the field it filters, written out to plain XML. Read it and you recover the complete list of customers, vendors, cost centres, employees, or projects in the underlying data — the entire dimension — whether or not any of them appear in the cells the recipient can see.
The item list leaks what the data contained; the selection flags leak what the author was thinking. A slicer saved with three of forty regions selected says the author’s last working view was those three regions — a far more pointed disclosure than the raw list. The selection is a frozen analytical decision: the segment under scrutiny, the accounts being chased, the cohort under review. It is the same kind of provenance the autofilter and sort state in a table leaks — the author’s last lens, preserved by accident.
The inference sharpens when the selection is small and pointed. A customer slicer left filtered to two named accounts, on a deal-pipeline pivot, in a file circulated to a partner, says something the author would never write in an email: these two are the ones that matter right now. A cost-centre slicer narrowed to a single department on a headcount model says where the cuts are being modelled. The button bar looks like neutral interface; the selection state behind it is a sentence about strategy.
Whatever the slicer was filtered to when you hit save is what it ships filtered to. The s="1" items are a candid record of the segment you were working on — the accounts, regions, or cost centres you singled out — recoverable without ever clicking a button.
The dangerous property of the slicer cache, exactly as with pivot and chart caches, is that it is decoupled from the visible state of the source. Three common “clean-up” actions all leave the cached item list fully intact while creating the impression that the data is gone:
slicers/slicer1.xml drawing, but Excel does not always reap the orphaned slicerCaches/slicerCache1.xml definition along with it. The cache can linger as an unreferenced part — the same orphaning seen when Convert to Range leaves a table part behind.In each case the author performs an action that feels like removing data and reasonably concludes the workbook is clean. The slicer still shows the right buttons, which reinforces the belief. But “the slicer still works” is precisely the symptom: it works because the full list of values is still there, frozen one layer down.
A timeline is a slicer specialised for dates — the horizontal scrubber that filters a pivot to a month, quarter, or year. It stores its state in a xl/timelineCaches/timelineCache1.xml part, and that part caches the full span of the date field — the earliest and latest dates present in the source — alongside the currently selected range. That span is itself a disclosure: it reveals how far back the underlying data reaches and how recent it is, independent of whatever window the timeline is currently showing.
The date bounds quietly answer questions the visible report was scoped to avoid. A timeline filtered to “Q4” for a board pack still caches a minimum date showing the dataset begins years earlier — revealing that prior periods exist and were deliberately scoped out. The selected range records exactly which window the author chose to present, and the cached bounds record the full extent of what they could have shown. As with the item slicer, the visible filter is the story the author tells; the cache is the story the data could tell.
A timeline showing “this quarter” still caches the earliest and latest dates in the underlying field. The presented window is a choice; the cached bounds disclose the full historical depth of the data, including the periods the report was scoped to leave out.
Beyond the item list, the slicer cache records its bindings: the sourceName of the field it filters and the names of the pivot tables or tables it controls. These names are organisational vocabulary, and they survive even when what they reference is no longer visible. A sourceName="Margin_Tier" tells a reader that the source data has a column called Margin Tier — a field that may not appear anywhere in the visible report. A pivotTable name="DealPipeline" names an analysis the author built, even if that pivot has since been deleted and only the orphaned slicer cache remains.
One slicer cache can also drive several pivots at once — the <pivotTables> list with more than one entry is a report-connection map, showing which views the author wired together to filter in lockstep. That structural picture — which fields exist, which pivots they steer, and what the author named each — is the same kind of internal map exposed by the defined-names symbol table and the calculation chain, recorded here as a side effect of making the buttons work.
Extracting a slicer’s full item list and selection needs only a ZIP reader and an XML parser. Walking every xl/slicerCaches/slicerCache*.xml part and reading the <i> items out of each reconstructs the filtered dimension directly from the control:
# dump every slicer cache: bound field, items, and selection state
import zipfile, re
from lxml import etree
def local(tag): return tag.rsplit("}", 1)[-1]
with zipfile.ZipFile("workbook.xlsx") as z:
for name in z.namelist():
if not re.match(r"xl/slicerCaches/slicerCache\d+\.xml", name):
continue
root = etree.fromstring(z.read(name))
print(name, root.get("sourceName"))
for i in root.iter():
if local(i.tag) == "i":
print(" ", i.get("n"), "selected" if i.get("s") == "1" else "")
The script prints, for every slicer, the field it filters and the complete list of items with their selection state — the excluded values right alongside the kept ones. For ad-hoc inspection, renaming the file to .zip, expanding it, and grepping xl/slicerCaches/ and xl/timelineCaches/ for <i surfaces every cached item in seconds. That is precisely the trivial unzip-and-read move that also exposes the shared-strings table and the chart caches.
From a single sweep through the slicer and timeline caches of a workbook, a reader typically extracts:
(at-risk), (confidential), or DO NOT CONTACT tags that travel verbatim in the item list.sourceName) that may not appear anywhere visible.The first four categories are the data and the author’s framing of it; the last three are structure and provenance. Together they routinely reconstruct an entire dimension of the source data — the full membership of a field the author believed they had filtered down to a safe subset.
Microsoft’s Document Inspector checks document properties, hidden sheets, comments, and a handful of other layers — but it has no concept of slicer-cache or timeline-cache data. From the inspector’s point of view a slicer is legitimate visible content the user deliberately created and wants to keep; stripping the list that makes its buttons appear would break the control, so the inspector leaves it entirely alone. There is no “remove cached slicer items” option, because the cache is not treated as removable metadata at all.
That places slicer caches in the same blind spot as chart caches, table schemas, and conditional-formatting rules: layers that carry real disclosure but that the inspector classifies as ordinary content. A workbook that has been “inspected and cleaned” ships every slicer cache untouched. Filtering the pivot does not help, hiding the source sheet does not help, and the one tool most users trust to find hidden data does not look here.
Document Inspector treats a slicer as content to keep, not metadata to remove, so it never reads the cache. A workbook can pass every inspector check and still carry the full membership of every filtered field, the author’s last selection, and the complete date range of the data behind a report scoped to show far less.
There is no single Excel UI action that empties a slicer’s cache while keeping the control, because the cache is what makes the control work. The realistic options trade off how much of the interactivity you need to preserve:
xl/slicerCaches/slicerCache*.xml, xl/timelineCaches/timelineCache*.xml, and xl/slicers/ / xl/timelines/ part, prune their entries from [Content_Types].xml and the workbook relationships, and remove the slicer references from the worksheet drawings — a complete pass, not just a deletion of the visible box.Whichever path you take, the orphaned cache is the easy thing to miss: deleting the on-sheet slicer feels like removing it, but the slicerCache definition can remain in the package as an unreferenced part, still listing every item. A complete pass enumerates the cache parts directly rather than trusting that removing the control removed the data.
xl/slicerCaches/slicerCache*.xml and xl/timelineCaches/timelineCache*.xml part directly — do not assume deleting the visible control removed them.<i> item; confirm the full list of distinct values is safe to disclose, including the ones filtered out.s selection flags — the chosen subset names the author’s focus and may itself be sensitive.(at-risk) or DO NOT CONTACT tags carried verbatim.sourceName and the bound pivotTable names for internal field names and deleted-pivot references.The slicer cache rarely travels alone. The same field it inventories is usually also frozen, row for row, in the pivot cache the slicer drives, plotted into a chart cache if a chart shares the pivot, preserved in the shared-strings table wherever those labels were typed into cells, and constrained by a data-validation list that may name the same master-data range. Stripping the slicer cache while leaving those siblings populated removes one copy of the dimension and ships several others. A workbook is only slicer-clean when the cache, the controls, and every parallel store of the same values are handled in one pass.
The broader lesson is the one this series keeps returning to: a workbook is a package of cooperating parts, and the same data is frequently stored in several of them at once. A slicer looks like the most innocent object in the file — a row of buttons, the opposite of raw data. In the format it is a verbatim, deduplicated inventory of an entire dimension of that data, sitting in plain XML behind a layer of interface.
A slicer is meant to be the safe, friendly face of a report — a control you add precisely so the recipient can explore the slice you decided to share. The cache quietly inverts that intention. Behind every button is the full list of values the field ever held; behind the current filter is a record of the exact subset you singled out; behind the timeline is the complete date span of data the report was scoped to narrow. None of it shows in the rendered control, and none of it is removed by filtering the pivot, hiding the source, or running Document Inspector. All of it is plain UTF-8 in xl/slicerCaches/ and xl/timelineCaches/, recoverable with a ZIP reader and a ten-line script.
For workbooks that stay inside an organisation, the cache is exactly what it was built to be: the thing that makes slicers instant and resilient. For workbooks crossing the perimeter, it is a full inventory of a dimension the author thought they had filtered away. The only durable defences are to flatten filtered reports to static values or pictures, or to strip the slicer, timeline, and cache parts in code — and to remember that in this format, the buttons were never the point. The list behind them is.
Use MetaData Analyzer to enumerate every slicer and timeline across every worksheet, read the full item list and selection state behind each one, recover the distinct values of fields filtered out of the visible report, surface the date ranges and bound-pivot names frozen into each cache, and confirm no slicer is shipping a dimension you never meant to disclose before your workbooks leave the organisation.
The pivot a slicer drives carries its own full copy of the source data — the same frozen-copy pattern that survives deleting the source sheet.
The same cache-survives-the-source story in the chart layer — a frozen data table the picture renders from and Document Inspector never touches.
Another control that embeds an organisational list in plain text — dropdowns and slicers both carry the dimension behind the interface.