Skip to main content Skip to footer

How to Add a Smart Angular Data Table Component to Your Web Application

Quick Start Guide
What You Will Need

Wijmo

Angular

Controls Referenced

FlexGrid

Tutorial Concept Build a performant Angular data table to efficiently manage complex datasets through virtualization, configurable columns, custom templates, and integrated editing workflows.

HTML tables are a good starting point when a page only needs to show a few rows of static data. The moment users expect real application behavior - sorting, editing, column movement, keyboard navigation, virtualization, import/export, and consistent styling - the “just use a table” approach becomes a feature project of its own.

That is why many Angular teams reach for a data table or grid component. A smart data table is not just a prettier <table>; it is a UI layer for working with large, interactive datasets without forcing developers to rebuild grid infrastructure on every screen.

In this tutorial, we will start with the capabilities developers usually expect from a smart Angular table, wire up an open-source Angular table, and then rebuild the same scenario with Wijmo’s FlexGrid to show where a purpose-built enterprise grid reduces custom code.

We will explore:

Ready to get started? Download Wijmo Today!

What Developers Expect from a Smart Angular Data Table

A smart table should help users explore, edit, and move data without making the application code harder to maintain. Common requirements include:

  • Data binding to arrays, APIs, databases, or remote services.
  • Sorting, filtering, searching, grouping, and paging.
  • Virtualization or incremental loading for large datasets.
  • Column resizing, reordering, pinning/freezing, and show/hide behavior.
  • Inline editing, validation, keyboard support, and copy/paste behavior.
  • Import/export workflows, especially Excel .xlsx in business applications.
  • Responsive layouts and cell-level visualizations such as templates, icons, progress indicators, and sparklines.

Open-source table libraries can be enough for many screens, especially when the requirements are narrow. Enterprise applications usually need stronger guarantees: consistent behavior across teams, framework wrappers, documentation, support, accessibility, and predictable upgrade paths.

Using Angular Data Tables

Angular gives teams a structured, TypeScript-first foundation for building single-page applications. That structure is useful in enterprise apps, but it also means UI components need to fit Angular conventions instead of fighting them. A good Angular table should work cleanly with component templates, typed data models, and Angular’s build pipeline.

For an open-source baseline, we will use ngx-datatable, an Angular component for large and complex data, with features such as virtual DOM handling, templates, horizontal and vertical scrolling, column reordering and resizing, pagination, sorting, and row selection.

Create the Angular Application

Start with a new standalone Angular application:

npx -p @angular/cli ng new smart-angular-data-table --standalone --routing=false --style=css
cd smart-angular-data-table
npm start

The application should appear as follows:

angular application

Create a small sales dataset that both table demos can share. Place it in src/app/data/recent-sales.ts:

export interface Sale {
  id: number;
  country: string;
  soldBy: string;
  client: string;
  description: string;
  value: number;
  itemCount: number;
}

export const recentSales: Sale[] = [
  { id: 1, country: 'Canada', soldBy: 'Bill', client: 'Cerberus Corp.', description: 'Prothean artifacts', value: 6250, itemCount: 50 },
  { id: 2, country: 'Canada', soldBy: 'Bill', client: 'Strickland Propane', description: 'Propane and propane accessories', value: 2265, itemCount: 20 },
  { id: 3, country: 'USA', soldBy: 'Ted', client: 'Dunder Mifflin', description: 'Assorted paper-making supplies', value: 4700, itemCount: 10 },
  { id: 4, country: 'USA', soldBy: 'Ted', client: 'Utopia Planitia Shipyards', description: 'Dilithium, duranium, assorted shipbuilding supplies', value: 21750, itemCount: 250 },
  { id: 5, country: 'USA', soldBy: 'Ted', client: 'Glengarry Estates', description: 'Desks, phones, coffee, steak knives, and one Cadillac', value: 5000, itemCount: 5 },
  { id: 6, country: 'Germany', soldBy: 'Angela', client: 'Wayne Enterprises', description: 'Suit armor and run-flat tires', value: 35000, itemCount: 25 },
  { id: 7, country: 'Germany', soldBy: 'Angela', client: 'Stark Industries', description: 'Armor and rocket fuel', value: 25000, itemCount: 10 },
  { id: 8, country: 'Germany', soldBy: 'Angela', client: 'Nakatomi Trading Corp.', description: 'Fire extinguishers and replacement windows', value: 15000, itemCount: 50 },
  { id: 9, country: 'UK', soldBy: 'Jill', client: 'Spaceley Sprockets', description: 'Anti-gravity propulsion units', value: 25250, itemCount: 50 },
  { id: 10, country: 'UK', soldBy: 'Jill', client: 'General Products', description: 'Ion engines', value: 33200, itemCount: 40 }
];

Add an Open-Source Angular Data Table

Install ngx-datatable and Bootstrap:

npm i @swimlane/ngx-datatable bootstrap

Then, create a standalone component for the open-source version. The component imports NgxDatatableModule directly and binds the shared sales array to the table rows:

import { Component } from '@angular/core';
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import { recentSales } from '../data/recent-sales';

@Component({
  selector: 'app-open-source-demo',
  standalone: true,
  imports: [NgxDatatableModule],
  styleUrl: './open-source-demo.css',
  templateUrl: './open-source-demo.html'
})
export class OpenSourceDemoComponent {
  rows = recentSales;
  editing: Record<string, boolean> = {};

  updateValue(event: Event, field: string, rowIndex: number): void {
    const value = (event.target as HTMLInputElement).value;
    this.editing[`${rowIndex}-${field}`] = false;
    this.rows[rowIndex] = { ...this.rows[rowIndex], [field]: value };
    this.rows = [...this.rows];
  }
}

The initial table markup is straightforward:

<ngx-datatable class="bootstrap" [rows]="rows" [headerHeight]="50" [rowHeight]="40">
  <ngx-datatable-column name="ID" prop="id"></ngx-datatable-column>
  <ngx-datatable-column name="Country" prop="country"></ngx-datatable-column>
  <ngx-datatable-column name="Sold By" prop="soldBy"></ngx-datatable-column>
  <ngx-datatable-column name="Client" prop="client"></ngx-datatable-column>
  <ngx-datatable-column name="Description" prop="description"></ngx-datatable-column>
  <ngx-datatable-column name="Value" prop="value"></ngx-datatable-column>
  <ngx-datatable-column name="Item Count" prop="itemCount"></ngx-datatable-column>
</ngx-datatable>

The sales data should now display when you run the application:

open source demo

Custom Cell Editing in ngx-datatable

To make a cell editable, you can replace the plain column with a cell template that toggles between a display span and an input. The pattern works, but it is custom code that you must repeat or abstract for every editable field:

<ngx-datatable-column name="Client" prop="client">
  <ng-template ngx-datatable-cell-template let-rowIndex="rowIndex" let-value="value">
    <span
      title="Double-click to edit"
      *ngIf="!editing[rowIndex + '-client']"
      (dblclick)="editing[rowIndex + '-client'] = true">
      {{ value }}
    </span>
    <input
      *ngIf="editing[rowIndex + '-client']"
      autofocus
      type="text"
      [value]="value"
      (blur)="updateValue($event, 'client', rowIndex)" />
  </ng-template>
</ngx-datatable-column>

These changes add support for editing the Client and Description columns in ngx-datatable, with changes automatically persisted to the underlying data source.

edit columns

This is the trade-off: ngx-datatable gives you a flexible baseline, but richer interaction often becomes custom Angular template code. That may be acceptable for one table. Across many business screens, the maintenance cost grows quickly.

When to Choose a Commercial Data Component

MESCIUS offers several JavaScript data products that target different data experiences:

Product Best Fit Highlights
SpreadJS Excel-like spreadsheet applications JavaScript spreadsheet experiences with Excel import/export, a high-speed calculation engine, dashboards, forms, reports, and 500+ Excel functions.
DataViewsJS Data presentation beyond a traditional grid Tree, card, masonry, trellis, timeline, Gantt, calendar, and grid layouts, with Angular, React, and Vue wrappers.
Wijmo FlexGrid High-performance Angular data grid scenarios Excel-like grid behavior, templates, virtualization, sorting, editing, grouping, filtering, import/export, and framework support for Angular, React, Vue, and PureJS.

Build the Same Angular Data Table with Wijmo FlexGrid

Now, let us replace the table with Wijmo FlexGrid. The important difference is that common grid interactions - editing, sorting, resizing, and column dragging - are built into the grid instead of being hand-coded in cell templates.

Install the packages needed for the grid demo:

npm i @mescius/wijmo.angular2.grid @mescius/wijmo.styles
npm i @mescius/wijmo.grid.xlsx jszip

Add the Wijmo stylesheet. You can place this in styles.css or the component stylesheet:

@import "@mescius/wijmo.styles/wijmo.css";
@import "bootstrap/dist/css/bootstrap.css";

Create a standalone Angular datagrid component using FlexGrid:

import { Component, ViewChild } from '@angular/core';
import * as wjcGrid from '@mescius/wijmo.grid';
import { WjGridModule } from '@mescius/wijmo.angular2.grid';
import { FlexGridXlsxConverter } from '@mescius/wijmo.grid.xlsx';
import { recentSales, Sale } from '../data/recent-sales';

@Component({
  selector: 'app-flexgrid-demo',
  standalone: true,
  imports: [WjGridModule],
  styleUrl: './flexgrid-demo.css',
  templateUrl: './flexgrid-demo.html'
})
export class FlexGridDemoComponent {
  @ViewChild('flex') flex?: wjcGrid.FlexGrid;
  sales: Sale[] = recentSales;

  load(input: HTMLInputElement): void {
    const file = input.files?.[0];
    if (!file || !this.flex) return;

    FlexGridXlsxConverter.loadAsync(this.flex, file, {
      includeColumnHeaders: true
    });
    input.value = '';
  }

  save(): void {
    if (!this.flex) return;

    FlexGridXlsxConverter.saveAsync(
      this.flex,
      { includeColumnHeaders: true, includeCellStyles: false },
      'FlexGrid.xlsx'
    );
  }
}

Use explicit columns so the grid order, widths, and formatting are easy to scan:

<div class="card main-panel">
  <div class="card-header"><h1>Wijmo FlexGrid Demo</h1></div>
  <div class="card-body">
    <wj-flex-grid #flex [itemsSource]="sales" [autoGenerateColumns]="false">
      <wj-flex-grid-column header="ID" binding="id" [width]="60" [isReadOnly]="true"></wj-flex-grid-column>
      <wj-flex-grid-column header="Client" binding="client" [width]="150"></wj-flex-grid-column>
      <wj-flex-grid-column header="Description" binding="description" [width]="320"></wj-flex-grid-column>
      <wj-flex-grid-column header="Value" binding="value" format="n2" [width]="110"></wj-flex-grid-column>
      <wj-flex-grid-column header="Quantity" binding="itemCount" format="n0" [width]="100"></wj-flex-grid-column>
      <wj-flex-grid-column header="Sold By" binding="soldBy" [width]="100"></wj-flex-grid-column>
      <wj-flex-grid-column header="Country" binding="country" [width]="100"></wj-flex-grid-column>
    </wj-flex-grid>
  </div>
  <div class="card-footer">
    <input #importFile type="file" accept=".xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
    <button type="button" (click)="load(importFile)">Import</button>
    <button type="button" (click)="save()">Export</button>
  </div>
</div>

When you run the application, the sales data is displayed in the FlexGrid:

Angular datagrid

Editing Grid Cell Values with FlexGrid

FlexGrid cells are editable by default when the grid and column allow editing. Users can double-click a cell or use the keyboard to edit in place. To make a field read-only, set isReadOnly on that column:

<wj-flex-grid-column header="ID" binding="id" [width]="60" [isReadOnly]="true"></wj-flex-grid-column>

editing cells

Sorting and Column Reordering with FlexGrid

FlexGrid allows users to sort by clicking column headers. When a column should not be sortable, set allowSorting to false on that column:

<wj-flex-grid-column header="Client" binding="client" [width]="150" [allowSorting]="false"></wj-flex-grid-column>

Column dragging is also enabled for FlexGrid columns by default. Disable dragging for an individual column with allowDragging:

<wj-flex-grid-column header="Client" binding="client" [width]="150" [allowDragging]="false"></wj-flex-grid-column>

column dragging

Import Excel Data into FlexGrid

The import button in the template calls load(importFile).

Import Excel

The component then passes the selected file to FlexGridXlsxConverter.loadAsync.

Excel data

This keeps file access in the template and removes the need for document.getElementById. The async converter API requires JSZip 3.0, which is why jszip was installed with the Excel package.

Angular datagrid demo

Export FlexGrid Data to Excel

The save() method calls FlexGridXlsxConverter.saveAsync and writes the grid data to FlexGrid.xlsx. Include headers for a spreadsheet users can open immediately, and disable cell styles when you want a smaller, data-focused export.

Export Excel

You can now open the Excel file exported from the FlexGrid component.

Exported Excel file

Ready to try it out? Download Wijmo Today!

Conclusion

There are many ways to add smart tables to Angular applications. Open-source projects can be a solid fit for lightweight scenarios, especially when your team is comfortable writing and maintaining the extra templates and behaviors around them.

However, for enterprise applications, the question is less “Can we make this work?” and more “How much grid code do we want to own?” Wijmo FlexGrid provides a compact, Angular data grid with built-in editing, sorting, virtualization, column operations, Excel import/export, templates, and more. FlexGrid lets developers spend less time rebuilding table infrastructure and more time shipping the business features around the data. Download the complete sample to try this tutorial out today.

 

Tags:

comments powered by Disqus