Structure of a report¶
Exercise report-structure-annex.pdf · PDF
Do you have a supermarket receipt in your pocket or your bag? Where do you look to know how much you paid? And where do you look to check one product? You find both in two seconds, and nobody ever taught you how.
That is not luck. Every receipt in the world has the same structure, and so does every bank statement, phone bill and school report card. You have been reading reports since you were six. In this unit you learn to write them, and today you start where every good report starts: with its parts, on a drawing, before any code.
What you will learn
- Define a report: data arranged to answer one question for a reader
- Name the eight bands of a report, and say how many times each one appears
- Tell a group footer from a report footer, and a page footer from both
- Write a spec card for a report before you draw it
- Build the wireframe of a report for your own app in Figma
- The trap: "a report is just a table"
Data is not a report¶
A report is data arranged to answer one question for a reader.
We will keep one object all the way through this page: the receipt. The supermarket's database holds thousands of sales. Your receipt answers one question for one reader: what did I buy, and how much do I owe?
That is also how a report differs from an ordinary screen of an app:
| A screen of the app | A report | |
|---|---|---|
| Purpose | Work with the data: create, edit, delete | Read the data: answer a question, decide something |
| Rows | Whatever is there now | Chosen by filters (this month, this folder) |
| Order | The user sorts as they like | Fixed: groups, then rows inside each group |
| Numbers | Raw | Calculated values, counts and totals added |
| Lifetime | Changes every second | A photo of a moment: it has a date, and it can be printed or exported |
Careful: a report is not just a table
A table shows rows. A report adds what the rows do not say: which rows were chosen, how they group, what they add up to, and when the photo was taken.
The eight bands¶
A band is a horizontal strip of a report with one job.
Here is a receipt from an invented shop, the Mercat Son Ferrer. Read it from top to bottom:
MERCAT SON FERRER
Ticket 2041 · 19/01/2027 · 18:42 ← report header
Item Qty EUR ← column header
FRUIT AND VEG ← group header
Bananas 1 1.35 ← detail
Tomatoes 1 2.10 ← detail
2 items 3.45 ← group footer
DAIRY ← group header
Milk 1 1.60 ← detail
Yoghurt 1 2.55 ← detail
2 items 4.15 ← group footer
BAKERY ← group header
Bread 1 1.10 ← detail
1 item 1.10 ← group footer
TOTAL · 5 lines 8.70 ← report footer
VAT included · Thank you ← page footer
For each band, only one question matters: how many times does it appear?
| Band | Appears | On the receipt |
|---|---|---|
| Report header | Once, at the start | Shop name, ticket number, date and time |
| Page header | At the top of every page | Not here: a receipt has one page. In a 3-page report, the title repeated in small type |
| Column header | At the top of the table | Item · Qty · EUR |
| Group header | Once per group | FRUIT AND VEG · DAIRY · BAKERY |
| Detail (or body) | Once per data row | Bananas 1.35, Tomatoes 2.10... |
| Group footer | Once per group | 2 items · 3.45: the subtotal |
| Report footer | Once, at the end | TOTAL · 5 lines · 8.70: the grand total |
| Page footer | At the bottom of every page | "VAT included · Thank you". In a long report: page 1 / 3 |
Stacked up, a two-page report looks like this:
flowchart TB
subgraph P1["Page 1"]
A["<b>Report header</b><br>once in the whole report"] --> B["<b>Column header</b>"]
B --> C["<b>Group header</b><br>FRUIT AND VEG"]
C --> D["<b>Detail</b><br>one per row"]
D --> E["<b>Group footer</b><br>subtotal"]
E --> F["<b>Page footer</b><br>page 1 / 2"]
end
subgraph P2["Page 2"]
G["<b>Page header</b><br>title in small type"] --> G2["<b>Column header</b><br>repeated for the table"]
G2 --> H["<b>Group header</b><br>DAIRY"]
H --> I["<b>Detail</b>"]
I --> J["<b>Group footer</b><br>subtotal"]
J --> K["<b>Report footer</b><br>grand total, once"]
K --> L["<b>Page footer</b><br>page 2 / 2"]
end
P1 --> P2
Why subtotals exist¶
Add the group footers of the receipt: 3.45 + 4.15 + 1.10 = 8.70. It matches the report footer. Now imagine the total said 8.90. Where would you look? At the group footers first, then at the detail of the wrong group. Subtotals are there so that a human can check.
Two pairs everybody mixes up¶
| One | The other | The difference | |
|---|---|---|---|
| Group footer vs report footer | One per group | One per report | Subtotal against grand total |
| Page footer vs report footer | One per page | One per report | The page footer belongs to the paper (page number). The report footer belongs to the data (totals) |
A 3-page report has three page footers and one report footer.
You will meet these bands at work
Report generators have used bands for decades. Only some names change. In JasperReports the report header is called title and the report footer is called summary. Crystal Reports calls its sections Report Header, Page Header, Group Header, Details, Group Footer, Report Footer and Page Footer.
Design before code¶
Think back to moving a component. In Figma it takes seconds; in Svelte it can take an afternoon. A report has a second cost, because every band needs data behind it. If you discover in code that you need a subtotal per month, you rewrite the query, the grouping and the template. In a wireframe, you drag one grey box.
So a report starts with a spec card: eight lines, in this order, that you fill in before you draw anything.
A spec card is a short written description of a report: its question, its reader, its data, its columns, its grouping, its calculated value, its totals and its filters.
Our running example for the whole unit is NoteBox, a small notes app with 36 notes in 4 folders. It is going to report on its own notes:
| Line of the spec card | NoteBox notes report |
|---|---|
| The one question it answers | "How much have I written, and where?" |
| Who reads it, and when | Me, at the end of each month |
| Data source | The notes of the app |
| Detail columns (4 to 6) | Title · created · words · reading time |
| Group by | Folder |
| Calculated value | Reading time = words ÷ 238, rounded up (minutes) |
| Totals | Count of notes, sum of words, sum of minutes |
| Filters | Folder · created from · pinned only |
If you cannot write the question in one sentence, you are not ready to draw the report. "Report of users" is a topic. "Which users have not logged in this year?" is a question.
More columns do not make a better report, either. If a column does not help to answer the question, it is noise.
Your report wireframe¶
A wireframe is a low-detail drawing of a screen or page: grey boxes that show what goes where, with no final styling.
Now it is your turn, for your own project app. Fill in the spec card, then build the report on an empty A4 frame in Figma (595 × 842). Give the frame a vertical auto layout, and the bands stack by themselves. Alt + drag copies a band.
Your wireframe needs:
| The wireframe has... | Detail |
|---|---|
| A report header | Title, the filters applied, and a date |
| A column header | 4 to 6 columns, with numbers on the right |
| One grouping | Group header, at least 3 detail rows and a group footer with a count and a subtotal. Show two groups |
| A report footer | Grand totals, and each one says what it adds up |
| A page footer | Page number and "generated on" |
| A chart placeholder (optional) | Only if you can write next to it the question it answers |
Four things usually go wrong:
- The calculated value is only another column of the data. Ask yourself which columns you compute it from. If the answer is "none", it is not calculated.
- You total things that cannot be added. The sum of dates or of phone numbers means nothing. A count always works.
- You have two levels of groups. One level is enough for now.
- You are designing the screen, with buttons. Today is the report itself, on paper. The screen that hosts it, with its filter controls, comes in the next lesson.
Is a report only for paper?
No. Most reports are read on a screen, inside the app. Paper, or a PDF, is one export of the same structure. That is why the bands are worth learning: they survive every format.
This wireframe is your contract for the rest of the unit. In the next lessons you give it data, a chart and a PDF version.
Key takeaways¶
- A report is data arranged to answer one question for a reader. It adds filters, groups, totals and a date to the rows.
- A report has eight bands: report header, page header, column header, group header, detail, group footer, report footer and page footer.
- The question for each band is how many times it appears: once per report, per page, per group or per row.
- The group footer holds a subtotal and the report footer holds the grand total. The page footer belongs to the paper, not to the data.
- A spec card comes first: if you cannot write the question, you cannot draw the report.
- A wireframe finds a missing subtotal in seconds. Code finds it in an afternoon.
Quick check¶
1. What makes a report different from a plain table of the same rows?
- It adds which rows were chosen, how they group, what they add up to, and the date
- It always has more rows and columns than the table, so nothing is left out
- It can only exist as a printed document, and never on the screen of an app
- It lets the user edit the rows directly, and it saves each change to the database
A table only shows rows. A report answers a question, so it also says what the rows do not: the filters, the groups, the totals and the moment of the photo. Most reports are read on a screen, and editing belongs to the ordinary screens of an app.
2. A report has 40 data rows in 5 groups, across 3 pages. How many report footers does it have?
- One
- Three
- Five
- Forty
The report footer appears once, at the end, with the grand total. There would be 3 page footers, 5 group footers and 40 detail rows. Asking "how many times does it appear?" is the fastest way to tell bands apart.
3. Where does the page number of a long report belong?
- In the page footer, because it describes the paper and not the data
- In the report footer, because it comes at the very end of the report
- In the group footer, because each group starts counting again from one
- In the detail band, because each row has to know which page it is on
The page footer repeats on every page and belongs to the paper. The report footer belongs to the data: it holds totals, and it appears only once.
4. A receipt's total does not match what you expected. Which band should you read first to find the mistake?
- The group footers, because each subtotal narrows the mistake down to one group
- The report header, because the date tells you when the mistake was made
- The column header, because the names of the columns may be in the wrong order
- The page footer, because it repeats the totals of all the pages of the report
Subtotals exist so that a human can check. Compare the group footers first, and then read the detail rows of the group that looks wrong.
5. Why is it worth writing a spec card and a wireframe before writing the code?
- Every band needs data behind it, and changing a band costs far less in a drawing
- Figma generates the final report code from the wireframe once it is finished
- A report cannot be compiled at all unless a wireframe exists in the project
- The wireframe stores the data of the report, so the code does not need a query
Discovering a missing subtotal in code means changing the query, the grouping and the template. In a wireframe, you drag one grey box. The spec card comes first, because it fixes the question the wireframe has to answer.
6. Which of these lines is a real question for a spec card?
- Which customers have not ordered anything this year?
- Report of the customers of the shop
- Customers and their orders, with totals
- Everything we know about each customer
Only the first can be answered, so only the first tells you which rows and columns belong in the report. The others are topics. A report needs one question, with a question mark.
7. A hospital canteen wants a monthly report: every meal sold, grouped by day, with the money taken each day and the money taken in the month. Pick the two correct statements.
- The money taken each day goes in the group footer
- The money taken in the month goes in the report footer
- The money taken each day goes in the page footer
- The money taken in the month goes in the column header
The group is the day, so its subtotal goes in the group footer. The whole month is the whole report, so its total goes in the report footer. A page footer depends on where the paper ends, not on the days.
You have the drawing. Now it needs real numbers: in the next lesson you load the data from different sources, and filter, calculate and total it in Data sources, filters and totals.