Sales Dashboard Template

This template is not a file you download. It is a column contract. Bring a CSV of sales rows carrying a date, a revenue figure and the categories you sell by, and the dashboard assembles itself around them: totals, a trend, product and region breakdowns, a channel mix. Seven column names are the entire specification, and the rest of this page explains why each one earns its place.

Load the template with sample data

The sample is the fastest way to see whether the layout fits before you go and find your own export. Six months of order lines, already in shape, rendered the moment the page opens.

Download the sample CSV and open it in a text editor if you would rather read the contract as rows.

The column contract

Every column below appears in the sample file, spelled exactly this way. The role is what the app infers from the values, and the role is what decides which panel a column can feed. Required means the layout loses a whole section without it.

Column What it holds Role Required What breaks without it
date The day the order was placed or booked, as an ISO date. date Required No trend, no period totals, no comparison against the previous period. The dashboard becomes a set of lifetime numbers with no sense of direction.
region The territory the sale belongs to, such as West or North. category Optional The geography breakdown disappears, so a region that is quietly carrying the quarter stays invisible inside the total.
product The item or SKU name sold on that row. category Optional You lose the top-products bar, which is usually the first panel anybody looks at and the only one that answers what is actually selling.
channel How the sale reached you: Direct, Partner, Online. category Optional The mix donut has nothing to split, so you cannot see the share of revenue that depends on somebody else's sales team.
units Quantity sold on that line. count Optional Volume and value can no longer be told apart, which hides the case where revenue held up only because prices went up.
unit_price Price per unit before any line total. currency Optional The average selling price KPI and any discounting view go away, since there is nothing to average across orders.
revenue Line total for the row, in one currency. currency Required Everything. Without a money measure the panels fall back to counting rows, and a count of order lines is not a sales dashboard.

Two of those columns are strictly redundant. units times unit_price should equal revenue, and if it does not, you have discounts, tax or rounding hiding in the gap. I kept all three in the contract deliberately, because that gap is often the most interesting number in the file and you cannot see it if the export only carries the total.

What you get

  • A revenue KPI strip. Total revenue for the period the file covers, total units, order count and average order value, each with the period stated underneath so nobody has to guess whether they are looking at a quarter or a year.
  • Revenue over time. A line at a grain chosen from the span of the date column, with the bucketing named in the caption. Six months of daily rows becomes monthly totals rather than a hundred and seventy unreadable ticks.
  • Top products. A horizontal bar of revenue by product, sorted descending, with the value written on each bar so the panel survives being screenshotted into a deck.
  • Revenue by region. The same shape against territory. Small territory counts stay as bars rather than a map, because five bars are read faster and more accurately than five shaded polygons.
  • Channel mix. A donut over channel with the percentage in the legend, which is the one panel executives reliably ask for and the one that ages best across quarters.
  • Units against revenue. A secondary panel that separates volume from value, so a flat revenue line with rising units reads as a pricing problem rather than a demand problem.

i. Bring these columns

Start from the contract table, not from your export. Write the seven names down, then go and find where each one lives in whatever system holds your orders. Usually five of the seven are already there under different headers and one or two have to be derived. That mapping exercise takes about ten minutes the first time and roughly zero minutes every time after, because you save the query.

One row per sale line is the grain that works. Not one row per customer, not one row per month, and not a spreadsheet where January is a column and February is the column next to it. If your file is already pivoted with periods across the top, unpivot it first; a wide file cannot produce a time series because the dates are header text rather than values.

ii. Drop the file

Drag the CSV in. Each column is read once and given a role, the panels bind themselves to the columns whose roles they need, and the dashboard renders. Nothing is uploaded and nothing is stored, which for a file full of deal amounts and customer territories is the part most people care about.

If a panel comes up empty, the cause is almost always in the file rather than in the panel. A revenue column exported with a currency code in a separate cell, a date column formatted as 03/04/2024 with no way to tell March from April, a stray total row at the bottom that becomes a category called Grand Total. All three show up immediately because the affected panel looks wrong in an obvious way.

iii. Adjust what you need

The arrangement is a starting point. Swap the product breakdown from sum to median and you get the typical order rather than the total, which is the number to quote when three enormous deals are distorting the average. Change the time grain from monthly to weekly for a shorter window. Drop the channel donut if you sell one way. Add a second breakdown on any category column you happen to have.

When it says what you want, export it. The whole dashboard goes out as an image or a PDF, and any single panel can hand you the exact aggregated numbers behind it as CSV, which is how you stop the chart in the deck and the table in the appendix from disagreeing with each other.

Getting your export into this shape

Real sales exports come from one of two places and each one arrives bent in its own direction.

From a CRM. A Salesforce or HubSpot opportunity export gives you Close Date, Amount, Stage and Owner, with spaces in the header names and often a currency code column sitting beside the amount. Rename Close Date to date and Amount to revenue, then filter to closed-won rows before exporting. That filter is the step people skip, and skipping it produces a beautiful revenue trend that is really a pipeline trend and will not tie out to anything finance recognizes. Products usually live on line items in a child object, so if the product breakdown matters you need the line item report rather than the opportunity report. Territory is often a picklist on the account, not the opportunity, which means a join or a formula field before export.

From an order table. A Shopify, WooCommerce or internal database export is closer to the target grain already, because it is one row per line item. The work here is different. Order exports carry a header row per order and a line row per item, so an order_id repeats down the file with the shipping and discount amounts populated only on the first row. Split those out or you will double count. Prices often arrive in minor units, so 1227512 is twelve thousand dollars and needs dividing by a hundred. Refunds may appear as negative rows, which is correct and useful, or as a separate refunds table, which means your revenue total is gross until you subtract them.

Both sources tend to ship timestamps rather than dates, something like 2024-01-02T14:33:09Z with a time zone attached. That parses fine, and it will bucket by day in the tenant's UTC day rather than the seller's local day, which shifts a small number of orders across a month boundary. If month-end accuracy matters, truncate the timestamp to a date in your export query and be explicit about which time zone you truncated in.

What this template will not do

  • It will not refresh. The dashboard is built from the file you dropped. When next month's numbers land, drop next month's file. There is no connection to your CRM and no scheduled pull, by design.
  • It will not mix currencies. One revenue column means one currency. Convert before export, or split the file and build one dashboard per currency.
  • It will not forecast. No dashed projection line off the end of the trend. A projection drawn from six noisy months looks authoritative and is not.
  • It will not calculate quota attainment. Targets are not in this contract. If you have a target per rep or per region, the KPI dashboard template is the one built around target versus actual.
  • It will not deduplicate. If your export repeats an order across two rows, the revenue total counts it twice. Clean the file first in the app.
  • It will not model margin. Cost is not a column here, so every figure is revenue, never profit. Adding a cost column gives you something to chart, but the template will not compute margin for you.

Frequently Asked Questions

There is no file to download. What exactly am I getting?

A contract and a layout. The contract is the list of seven column names on this page. The layout is what the dashboard builds when it sees those names in a file: a revenue KPI strip, a revenue trend, product and region breakdowns and a channel mix. You supply the rows. Nothing is copied onto your machine, so there is no spreadsheet to keep in sync and no formula to repair when somebody inserts a column.

Do my column names have to match exactly?

Close is usually good enough, and exact is guaranteed. Roles are read from the values before the header text, so a date column called order_date is still a date and a money column called net_amount is still money. What the exact names buy you is the titles: panels named revenue by region rather than net_amount by sales_geo. Renaming seven headers in a text editor takes a minute and it makes the dashboard readable by somebody who has never seen your export.

Can I use this if I only have revenue and no units or unit_price?

Yes. Revenue plus date plus one category is enough for most of the layout. You lose the average selling price KPI and the units-versus-revenue comparison, because both are arithmetic on columns that are not there. Everything else, the trend, the breakdowns, the totals, still builds. The contract table on this page marks exactly which columns are required and which are optional for this reason.

My CRM exports one row per opportunity, not per order. Does that work?

It works, and it means something different. One row per opportunity with a close date and an amount gives you closed revenue over time, which is the right chart for a sales leader. It does not give you units or an average selling price unless the opportunity carries a quantity. Filter to won opportunities before you export, otherwise your revenue trend is a pipeline trend and the two numbers will not reconcile with finance.

What happens if my revenue column has currency symbols in it?

It is read as money. Dollar and euro signs, thousands separators, trailing minus signs and accounting parentheses are all parsed, so $12,275.12 and (529.49) both become numbers. What is not handled is a single column holding several currencies at once. Summing dollars and rupees in one total produces a confident and meaningless figure, so convert to one currency before you export or split the file by currency.

Does the dashboard aggregate my rows or show them one by one?

It aggregates. Every panel is a sum, an average or a count over groups, never a list of raw rows, which is why a file with three hundred thousand order lines draws as quickly as one with three hundred. The underlying rows stay available in the table view if you want to check a number, and the aggregated values behind any panel can be exported as their own CSV.

Is my sales data uploaded anywhere?

No. Parsing, aggregation and drawing all happen inside your browser tab. There is no upload endpoint behind this page and no request carries your rows. This matters more for a sales export than for most files, because customer names, discounts and per-deal amounts are usually the most commercially sensitive thing a company keeps in a spreadsheet.

Can I add my own panels once the template has built?

Yes. The template is a starting arrangement, not a locked one. Add a panel, change an aggregate from sum to median, swap the dimension on any breakdown, remove what you do not need, and reorder the grid. A common first edit is switching the product breakdown from sum of revenue to median revenue per order, which tells you something the totals hide.

See the layout first

Open it with the sample, decide in thirty seconds whether it fits, then go and get your own export.

Load the template with sample data