Cover image for a step-by-step tutorial on building React Pivot Table report.

React Pivot Table: How to Create Interactive Reports

In this article, learn how to build a powerful, Excel-style pivot table in React that transforms massive datasets into interactive, browser-based reports.

What is React Pivot Table

A pivot table is your secret weapon for transforming raw numbers into compelling narratives. It’s more than just moving rows and columns around. It helps you interact with the data by grouping, filtering, and drilling down into details.

Imagine you’re a municipality in Zurich, managing a national database of thousands of registered dogs. When Excel can no longer handle the sheer volume of data, you need a more robust solution. So, you build your own interactive reports directly in the browser.

In this guide, we will show how to bring that kind of data exploration right into your React web app. Get ready to build a stunning React report that easily handles large datasets, offers seamless Excel-like filtering, and fundamentally changes how you view data in modern applications.

Here's the result you expect to get by the end of this tutorial:

Interactive dashboard showing the final result of this React Pivot Table tutorial. It displays dog breed analysis through pivot tables and a bar chart.

Get acquainted with this project on GitHub. Now, let’s dive into the tutorial and start building it yourself.

Step-by-step tutorial: creating a web report using React pivot table

Here's the plan: we'll build a mini analytics dashboard to explore Dogs of Zurich dataset and answer real-world questions like:

  • How many dogs of a specific breed live in each city district?
  • How does the popularity of the selected dog breeds vary across different age groups of dog owners in Zurich?
  • What are the top 10 most popular breeds born in 2010-2015?

We’ll use Flexmonster Pivot — a React-compatible JavaScript library for interactive data analysis and reporting — and integrate it into a Next.js application.

Creating a project

Let’s create a Next.js application:

npx create-next-app dogs-of-zurich --ts --app
cd dogs-of-zurich

To add Flexmonster to our project, firstly install Flexmonster CLI:

npm install -g flexmonster-cli

Then, run the following command inside the project to install Flexmonster Pivot wrapper for React projects:

flexmonster add react-flexmonster

Great! The next step is to add a pivot table to our page. We need to create a wrapper around FlexmonsterReact.Pivot. For that, we made a file called PivotWrapper with the following configurations:

"use client";
import * as React from "react";
// FM must be imported like this so we can use refs
import * as FlexmonsterReact from "react-flexmonster";
import Flexmonster from "flexmonster";
import "flexmonster/lib/flexmonster.highcharts.js";

// A custom type so we can pass a reference along with other Flexmonster params
type PivotProps = Flexmonster.Params & {
ref?: React.Ref<FlexmonsterReact.Pivot>;
};

const PivotWrapper: React.FC<PivotProps> = ({ ref, ...fmConfigs }) => {
return <FlexmonsterReact.Pivot {...fmConfigs} ref={ref} />;
};

export default PivotWrapper;

Super! With all the necessary setup complete, it's time to integrate the empty pivot table to app/page.tsx:

"use client";
import * as React from "react";
// Types are static, so we can safely import it for use in references
import type { Pivot } from "react-flexmonster";
import dynamic from "next/dynamic";

// Wrapper must be imported dynamically, since it contains Flexmonster pivot
const FlexmonsterPivot = dynamic(() => import("@/app/PivotWrapper"), {
ssr: false,
loading: () => <h1>Loading Flexmonster...</h1>,
});

export default function Dashboard() {
const pivotRef: React.RefObject<Pivot | null> = React.useRef<Pivot>(null);

return (
<>
<FlexmonsterPivot ref={pivotRef} toolbar={true} />
</>
);
}

After the previous step, you will see a working but empty (for now) component.

With our project now established, the next step is to get our data into the pivot table.

Loading data

If you are working with a small file, it is perfectly fine to connect to it directly using filename property. However, in this example, we want to show you a powerful tool for working with large datasets — Flexmonster Data Server. It allows us to load and configure massive data volumes with just a few simple settings. The Data Server is an installable, server-side application that comes with a built-in Admin Panel — a graphical interface that simplifies managing data sources.

Open Admin Panel and click Add New Indexes:

Screenshot of the Flexmonster Data Server Admin Panel, displaying the 'Indexes' screen with the 'Add New Index' button highlighted. This panel is used to manage data sources for large datasets.

Then, choose Type CSV. Enter a new index name and select the path to your dataset. Additionally, you can configure a delimiter, different separators, and refresh time. For that dataset, we decided to keep the default configurations. Click Create:

Screenshot of the Flexmonster Data Server Admin Panel's 'Add New Index' form. It shows the configuration for adding a CSV dataset, with 'dogs_of_zurich' as the index name and the 'Create' button highlighted.

You should see the following window:

Screenshot of the Flexmonster Data Server Admin Panel's 'Indexes' screen, showing the 'dogs_of_zurich' CSV index successfully listed and enabled. This confirms the data source is ready.

Great! Now, return to our code. Let’s define the dataSource property to connect to the Flexmonster Data Server, which delivers preprocessed data for visualization:

const dataSourceConfig = {
type: "api",
url: "http://localhost:9500",
index: "dogs_of_zurich",
};

const report = {
dataSource: dataSourceConfig
};

export default function Dashboard() {
const pivotRef: React.RefObject<Pivot | null> = React.useRef<Pivot>(null);

return (
<>
<FlexmonsterPivot
ref={pivotRef}
toolbar={true}
height="900"
width="650"
report={report}
/>
</>
);
}

For this tutorial, we worked with a CSV file using Flexmonster Data Server. However, Flexmonster supports a wide range of other data sources — including JSON files, relational databases, MongoDB, Elasticsearch, OLAP cubes, and more. 

Now that we’ve connected the data, let’s dive into the data analysis.

Analyze the data

Hmm… Here is the problem: I don't speak German. Let's specify the field's custom caption using mapping:

const dataSourceConfig = {
type: "api",
url: "http://localhost:9500",
index: "dogs_of_zurich",
mapping: {
HALTER_ID: { caption: "Owner ID" },
ALTER: { caption: "Owner Age" },
GESCHLECHT: { caption: "Owner Gender" },
STADTKREIS: { caption: "City District" },
STADTQUARTIER: { caption: "Neighborhood" },
RASSE1: { caption: "Breed 1" },
RASSE1_MISCHLING: { caption: "Breed 1 Mixed" },
RASSE2: { caption: "Breed 2" },
RASSE2_MISCHLING: { caption: "Breed 2 Mixed" },
RASSENTYP: { caption: "Breed Type" },
GEBURTSJAHR_HUND: { caption: "Dog Birth Year" },
GESCHLECHT_HUND: { caption: "Dog Gender" },
HUNDEFARBE: { caption: "Dog Color" },
},
};

Alright! It’s time to finally answer our first question: "How many dogs of a specific breed live in each city district?" You can do it in a second using slice:

const report = {
//…
slice: {
rows: [
{
uniqueName: "STADTKREIS", // City District
},
{
uniqueName: "RASSE1", // Breed 1
},
],
columns: [
{
uniqueName: "[Measures]",
},
],
measures: [
{
uniqueName: "HALTER_ID", // Owner ID - A key
aggregation: "count",
},
],
},
};
Screenshot of the Flexmonster React Pivot Table's initial grid view. It displays data aggregated by 'CITY DISTRICT' and 'Total Count of Owner ID', ready for further analysis to answer specific questions about dog data.

Looks great! But we prefer classic form — more like Excel, which many users find familiar and convenient:

const report = {
//…
options: {
grid: {
type: "classic",
},
},
};
Screenshot of the React Pivot Table displaying dog data in a classic, Excel-style grid. It shows counts by 'CITY DISTRICT' and 'BREED', illustrating the familiar report layout configured by code.

By the way, you can double-click on the values for each district to open a drill-through view, which shows all records for that district, including each dog breed and dog owner’s ID. For example:

Screenshot of a React Pivot Table grid, with a red arrow pointing to the '123' value for 'CITY DISTRICT 1'. This highlights where to double-click to open a drill-through view for detailed data records.
Screenshot of the React Pivot Table's 'Details' popup window, showing raw data records after a drill-through. It displays individual 'CITY DISTRICT', 'BREED', and 'OWNER ID' entries.

Great job! Now you know how to build a basic report, customize its layout, and count values in seconds. You're officially ready to analyze anything from the number of Golden Retrievers in District 3 to the Dachshund density across the whole city.

Heat map

Now, let's answer the second question: "How does the popularity of the selected dog breeds vary across different age groups of dog owners in Zurich?". Use Count aggregation to count Owners' IDs of each age group. We have chosen six breeds using the slice.filter property:

const secondReport = {
dataSource: dataSourceConfig,
slice: {
columns: [
{
uniqueName: "RASSE1",
filter: {
members: [
"RASSE1.[Labrador Retriever]",
"RASSE1.[Chihuahua]",
"RASSE1.[Pudel]",
"RASSE1.[Jack Russel Terrier]",
"RASSE1.[Yorkshire Terrier]",
"RASSE1.[Mops]",
],
},
},
],
rows: [{ uniqueName: "ALTER" }],
measures: [
{
uniqueName: "HALTER_ID",
aggregation: "count",
},
],
},
};

export default function Dashboard() {
const pivotRef2 = React.useRef<Pivot>(null);
//…

return (
<FlexmonsterPivot
ref={pivotRef2}
width="100%"
height="800"
report={secondReport}
/>
);
}
Screenshot of a React Pivot Table answering 'How does the popularity of top dog breeds vary across different owner age groups?'. The table shows 'OWNER AGE' rows and 'BREED' columns with counts of owner IDs.

Love it! Based on our pivot table, let’s apply another data visualization: a Heat map, which represents the magnitude of individual values within a dataset as a color. Define a function for customizing and then add it to a customizeCell parameter to the component. 

I used Flexmonster Heat map React Demo with the TinyColor library as a reference:

import tinycolor from "tinycolor2";

const colorScheme = [
"#DF3800",
"#FF6D1E",
"#FF9900",
"#FFB600",
"#A5CE31",
"#6CBD05",
"#00A45A",
];

const minValue = 0;
const maxValue = 120;

const customizeCellFunction = (
cell: Flexmonster.CellBuilder,
data: Flexmonster.CellData,
) => {
if (data.measure && !data.isGrandTotal) {
let backgroundColor = getColorFromRange(data.value!);
let textShadowColor = tinycolor(backgroundColor).darken(15).toString();
let borderColor = tinycolor(backgroundColor).darken(10).toString();

cell.style = {
...cell.style,
"background": backgroundColor,
"color": "white",
"font-weight": "bold",
"text-shadow": `0px 2px 3px ${textShadowColor}`,
"border-bottom": `1px solid ${borderColor}`,
"border-right": `1px solid ${borderColor}`,
};
}
};

export default function Dashboard() {
const pivotRef2 = React.useRef<Pivot>(null);
//…

return (
<FlexmonsterPivot
ref={pivotRef2}
width="100%"
height="800"
customizeCell={customizeCellFunction}
report={secondReport}
/>
);
}
Screenshot of a React Pivot Table displaying a heatmap of dog breed popularity across owner age groups. Cell colors visually represent the count of owner IDs, providing intuitive data visualization.

The heat map highlights clear trends in breed preferences across age groups. Brighter greens indicate higher counts, showing that Labrador Retrievers and Chihuahuas are especially favored by owners aged 31–60. Warmer tones (orange to red) reflect lower counts, revealing a steady decline in dog ownership with increasing age, particularly among those over 70. This visual encoding makes it easy to spot generational patterns and popular breed choices at a glance.

Charts

Another great way to present data is through charts! Flexmonster has its own built-in interactive charts. But also you can use Highcharts, amCharts, FusionCharts, Google charts, and other libraries

Today I will show you how to use Highcharts by answering our third question: “What are the top 10 most popular breeds born in 2010-2015?” 

First, let’s prepare our report. We will filter by value to select only the most popular breeds. Set the filter.query property to show the top 10 values, based on the Count aggregation of the Owner ID measure.

const thirdReport = {
dataSource: dataSourceConfig,
slice: {
rows: [
{
uniqueName: "RASSE1",
filter: {
measure: {
uniqueName: "HALTER_ID",
aggregation: "count"
},
query: {
top: 10,
},
},
},
],
columns: [
{
uniqueName: "GEBURTSJAHR_HUND",
filter: {
query: {
between: [2010, 2015]
},
},
},
{
uniqueName: "[Measures]"
},
],
measures: [
{
uniqueName: "HALTER_ID",
aggregation: "count"
},
],
},
};

Note You must have a license key to work with any charting library. If you don't have one, contact the Flexmonster team and request a special trial key.

Import Highcharts and add reportComplete event handler to know when the pivot table is ready to be a data provider:

import * as Highcharts from "Highcharts";

export default function Dashboard() {
const pivotRef3 = React.useRef<Pivot>(null);

const reportComplete = () => {
pivotRef3.current!.flexmonster.off("reportComplete", reportComplete);
};

<FlexmonsterPivot
ref={pivotRef3}
width="100%"
height="600"
report={thirdReport}
reportcomplete={reportComplete}
/>;
}

Now, let’s define the bar type in the CreateBarChart function. I recommend exploring other Highcharts types that you can use for your application. 

Add a container for the chart:

function createBarChart(pivot: Pivot) {
pivot.flexmonster.highcharts?.getData(
{ type: "bar" },
(data: any) => Highcharts.chart("highcharts-container", data),
(data: any) => Highcharts.chart("highcharts-container", data)
);
}

export default function Home() {
const pivotRef3 = React.useRef<Pivot>(null);

const reportComplete = () => {
pivotRef3.current!.flexmonster.off("reportComplete", reportComplete);
createBarChart(pivotRef3.current!);
};

return (
<div>
<div style={{ visibility: "hidden" }}>
<FlexmonsterPivot
ref={pivotRef3}
height="0"
report={thirdReport}
reportcomplete={reportComplete}
/>
</div>
<div className="highcharts-container">
</div>
);
}

Also, you can use UI for further data exploration. For example:

Horizontal bar chart from the React Pivot Table report, visualizing the top dog breeds born between 2010-2015.

Excellent! From the chart, we can see that Chihuahuas, Labrador Retrievers, and Mischling Klein were leading the pack during those years. Now that you’ve mastered charting, you're ready to sniff out more insights! 😀

Final result

Let’s adjust our pivot tables and the chart and create a dashboard. We also recommend you to read more about available customization options in Flexmonster.

🐶 So, here we got our interactive dashboard:

Final result of tutorial  React pivot table Interactive dashboard showing the final result of this React Pivot Table tutorial. It displays dog breed analysis through pivot tables and a bar chart.

Why Use Flexmonster React Pivot Table?

When building a React pivot table component for a modern web application, choosing a solution that balances performance, functionality, and ease of integration is important. After evaluating several tools, Flexmonster proved to be a practical option for handling multi-dimensional data in React.

The advantages: performance and interactivity

Flexmonster is optimized for creating React pivot tables that handle large datasets. In our case, we used Flexmonster Data Server to handle data aggregation on the backend. The separation between backend data processing and frontend rendering allows the UI to stay responsive even under heavy load. 

Use cases

Whether you're building financial dashboards, e-commerce analytics platforms, or internal reporting tools, Flexmonster provides the flexibility to meet a wide range of business needs. It's commonly used in SaaS dashboards, enterprise reporting modules, and internal BI tools — especially where multi-dimensional data needs to be explored by non-technical users.

Functionalities

Flexmonster offers all key features expected from a modern React pivot grid:

  • Built-in aggregation functions
  • React table filtering and sorting with an Excel-like UI
  • Drag-and-drop field layout
  • Integration with charting libraries like Highcharts, FusionCharts, and others
  • Conditional formatting and calculated fields for advanced customization

These features reduce development time and allow quick assembly of flexible data visualization tools.

Support, documentation, community 

Flexmonster provides clear documentation, live demos, and a helpful technical support team ready to assist. There's also a growing community of developers using the library, so you are never alone. 😀

Alternatives to Flexmonster

Before settling on Flexmonster, I spent some time digging through what developers actually use for pivot tables in React. This Reddit thread helped — most people want something powerful, easy to plug into a React app, and not buried inside a massive UI library. Same vibe in this one: drag-and-drop, decent performance, and ideally not a maintenance nightmare.

Sure, there are commercial alternatives — some look fine at first but often feel like pivot tables are just tacked on. They’re usually slower, bundled with stuff you don’t need, or haven’t seen accurate updates in years.

But if all you need is something quick and free to spin up a basic report — like a small internal tool — there are a couple of options worth checking out:

WebDataRocks (WDR)

A free JavaScript pivot table that runs entirely in the browser. It’s fast to set up, beginner-friendly and has an Excel-style UI. While it doesn’t offer deep customization or advanced charting out of the box, it’s a solid pick if you’re working with static datasets and want something easy to configure.

react-pivottable

A React wrapper around the well-known PivotTable.js library. It supports drag-and-drop and basic aggregations. It’s open-source and decently flexible, but you will need to invest some time if you want to customize the UI or hook it up to live data sources — it wasn’t built with large-scale performance in mind.

Conclusions

And just like that, we built a fully interactive React pivot table for real-world data — in minutes. With Flexmonster, we turned a raw dataset into a responsive, drag-and-drop reporting tool that feels fast, clean, and genuinely useful. Whether you're building internal dashboards, data-driven features, or customer-facing analytics, this setup gives you a solid foundation for modern, browser-based data exploration.

FAQ

What is a pivot table?

A pivot table is a powerful tool for summarizing, analyzing, and exploring large datasets. It lets users group, filter, and aggregate data dynamically — often with drag-and-drop. See JS Fiddle example of configuring the report in Flexmonster.


How to add a pivot table in React?

You can easily integrate a pivot table in React using the FlexmonsterReact.Pivot component. The official documentation provides a detailed guide, and you can also watch the step-by-step video tutorial for a visual walkthrough.


Where can I see React pivot table examples?

Subscribe to our news: