Ask a Looker admin where their numbers end up and the honest answer is rarely "in a Look". It is a spreadsheet someone downloaded last quarter, or a slide deck with a screenshot pasted into it. Every one of those exports is a fork in your semantic layer: the moment data leaves Looker as a CSV, it stops being governed, stops refreshing, and starts drifting from the definition in your LookML.
Google's answer is to stop fighting the spreadsheet and put the semantic layer inside it. Two surfaces matter:
- Connected Sheets for Looker — a Google Sheet talks to a Looker Explore live, with pivots, formulas and scheduled refresh, but the aggregation happens in your warehouse through LookML.
- Looker Reports — the Looker Studio reporting engine built into the Looker platform, so self-service report builders work against modelled Explores instead of extracts.
This tutorial walks both end to end, and — more usefully — covers the modelling and permission work that decides whether they are a win or a support burden.
Why this is a semantic-layer problem, not a BI-tool problem
A CSV export answers one question, once. A Connected Sheet answers it every morning using the same measure: net_revenue your dashboards use. The governance argument is simple:
| Export path | Definitions | Row-level security | Refresh | Audit trail |
|---|---|---|---|---|
| CSV download | Frozen copy | Applied once, then gone | Manual | None after download |
| Scheduled CSV to Drive | Frozen copy | Re-applied per send | Scheduled | Looker schedule history |
| Connected Sheets for Looker | Live LookML | Applied per query, as the signed-in user | On open / scheduled | System Activity |
| Looker Reports | Live LookML | Applied per query | On view | System Activity |
The last two rows are the only ones where a user attribute change on Monday actually changes what the finance analyst sees on Tuesday.
Part 1: Connected Sheets for Looker
Prerequisites
- A Looker (Google Cloud core) or Looker (original) instance reachable from Google Workspace.
- Users signed into Sheets with the same Google identity they use in Looker. This is the single most common setup failure: Connected Sheets authenticates as the Google user, so a Looker account provisioned with a different email will be told it has no access.
- The user needs
access_dataandexploreon the relevant model set.
Step 1: connect the sheet
In a Google Sheet: Data > Data connectors > Connect to Looker. Paste the instance URL (https://yourcompany.cloud.looker.com), then pick a model and an Explore. Looker returns the list of Explores the signed-in user is permitted to see — so model sets are doing real work here.
Once connected, the sheet holds a data source, not a data dump. Nothing is copied until the user builds something.
Step 2: build a pivot, not an extract
The trap is to click Extract and pull 50,000 rows. Teach users the other two paths:
- Pivot table — rows, columns, values chosen from LookML dimensions and measures; the GROUP BY runs in BigQuery/Snowflake.
- Calculated columns and formulas —
=formulas referencing the connected data, recalculated on refresh.
A pivot built on orders.created_month x products.category with orders.total_revenue is a few kilobytes in the sheet and one aggregate query in the warehouse. The same analysis built on an extract scans every order row and expires the moment someone adds a product.
Step 3: control refresh
Data > Refresh options gives manual, on-open, and scheduled (hourly/daily/weekly) refresh. Two rules:
- Set a schedule that is no fresher than your datagroup. Refreshing a sheet every hour against a PDT that rebuilds nightly just re-queries the same cached rows at full cost.
- For wide distribution, schedule one sheet and share it, rather than letting 40 viewers each trigger on-open refreshes against the warehouse.
Step 4: make the Explore spreadsheet-friendly in LookML
Connected Sheets exposes field labels and descriptions, not your field names. The model you were happy to ship for analysts is often hostile to spreadsheet users. Three quick wins:
explore: orders {
label: "Orders (Finance)"
description: "Approved orders only. Revenue is net of returns and excludes test accounts."
# Keep the field picker short: hide modelling plumbing from sheet users
fields: [ALL_FIELDS*, -orders.internal_hash, -orders.etl_batch_id]
# Protect the warehouse from an unfiltered full-table pivot
conditionally_filter: {
filters: [orders.created_date: "90 days"]
unless: [orders.order_id, orders.created_date]
}
}
measure: net_revenue {
type: sum
sql: ${TABLE}.net_revenue ;;
label: "Net Revenue"
description: "Gross revenue minus returns and discounts. Matches the finance close."
value_format_name: usd
}
value_format_name matters more than you think: Connected Sheets respects LookML formatting, so currencies and percentages land correctly instead of as raw floats someone re-formats by hand.
Step 5: keep row-level security intact
Connected Sheets queries run as the signed-in user, so your existing access_filter and user attribute work carries over unchanged:
explore: orders {
access_filter: {
field: orders.region
user_attribute: allowed_region
}
}
The caveat is the result, not the query: once a regional manager builds a pivot and shares the sheet with someone outside their region, the cached values in the sheet are visible even though a refresh by that second user would return their own slice (or an error). Treat sheet sharing as data sharing, and keep genuinely sensitive Explores out of Connected Sheets entirely by restricting the model set.
Part 2: Looker Reports
Looker Reports brings the Looker Studio editing canvas into Looker itself. For teams who have run Looker and Looker Studio side by side for years, this is the convergence step: one authentication, one semantic layer, reports stored as Looker content in Looker folders.
What changes versus standalone Looker Studio
| Looker Studio (standalone) | Looker Reports (in Looker) | |
|---|---|---|
| Data source | Any connector, often raw BigQuery | Your LookML Explores |
| Metric definitions | Re-created per report | Inherited from LookML |
| Permissions | Report-level sharing | Looker folders, model sets, RLS |
| Storage | Drive | Looker content, backed up with your instance |
| Governance | Loose | System Activity, content validator |
Step 1: enable and locate it
Reports appear in the Looker navigation alongside Dashboards and Looks (availability depends on your instance edition and release channel — confirm in Admin > Platform before you promise it to a stakeholder). Create a report, choose Looker as the data source, and pick model and Explore.
Step 2: build the report
The canvas is Looker Studio: free-form charts, text, images, page navigation, themes. The difference is the field list — it is your LookML dimensions and measures, with labels, descriptions and formatting already applied. Filters map to Explore filters; a date range control maps to your dimension group.
Step 3: decide what belongs here
This is the architectural judgement call consultants get paid for. A rough split:
- LookML dashboards — version-controlled, promoted between instances, business-critical. Anything that must not break.
- User-defined dashboards — operational, built by analysts, tiled layout, drillable.
- Looker Reports — presentation-grade, narrative, external or executive audiences; pixel layout matters more than drilling.
- Connected Sheets — ad-hoc analysis, reconciliation, anything that ends in a formula a human wrote.
If you cannot say which bucket a request belongs in, it usually belongs in a dashboard.
Governance: the five controls to set before you roll out
- Model sets. Decide which Explores are Workspace-facing. A "finance_sheets" model with a handful of curated Explores beats exposing 40 analyst Explores.
- Guardrails in LookML.
conditionally_filter,sql_always_where, andrequired_fieldsprevent a pivot that scans five years of fact data. Our guide to Explore guardrails covers the full set. - Caching. Point Workspace-facing Explores at a datagroup that matches your load schedule so repeated refreshes hit cache. See Datagroups and caching policies.
- Monitoring. Query the System Activity Explores for
history.sourceto see how much of your warehouse spend now originates in Sheets versus the Looker UI, and which users are the heaviest. Our System Activity tutorial has the starting queries. - A deprecation plan for the old exports. Rolling out Connected Sheets without retiring the scheduled CSVs doubles your surface area. Find the schedules in System Activity, contact the owners, migrate, delete.
Troubleshooting
| Symptom | Likely cause |
|---|---|
| "You do not have access to this Looker instance" in Sheets | Google identity does not match the Looker user's email, or the user lacks access_data/explore |
| Explore missing from the picker | Not in the user's model set, or hidden: yes on the Explore |
| Pivot times out | No conditionally_filter; query is scanning unpartitioned history |
| Numbers differ from a dashboard | Different filters, not different logic — check the date range control and any always_filter on the dashboard |
| Sheet refresh is slow but Looker is fast | Cache miss: refresh schedule is more frequent than the datagroup, or an extract rather than a pivot |
| Totals look doubled | Join fanout. Confirm symmetric aggregates are in play — see join fanout |
Where this leaves the semantic layer
Every surface Google has shipped recently — Connected Sheets, Looker Reports, the Conversational Analytics API, MCP servers for agents — consumes the same LookML model. The strategic consequence for Looker teams is that model quality is no longer an internal concern: labels, descriptions, value formats, guardrails and access filters are now the user interface for spreadsheets, reports and AI agents alike.
That is a good problem. It means the investment you make tidying one Explore pays off in four places at once.
Vistelio's senior Looker developers help BI teams curate Workspace-facing Explores, set guardrails and caching, and retire the CSV sprawl that comes before it. If you are planning a Connected Sheets or Looker Reports rollout, get in touch.