Skip to main content

Quick Start Guide

Get up and running with Tabulate in just a few minutes. This guide will show you how to create beautifully formatted tables with minimal code.

Your First Table

Let’s start with the simplest possible table:
#include <tabulate/table.hpp>
using namespace tabulate;

int main() {
  Table movies;
  
  movies.add_row({"Movie Name", "Director", "Release Year"});
  movies.add_row({"Toy Story 4", "Josh Cooley", "2019"});
  movies.add_row({"Sully", "Clint Eastwood", "2016"});
  
  std::cout << movies << std::endl;
}
1

Include the header

#include <tabulate/table.hpp>
using namespace tabulate;
2

Create a Table object

Table movies;
3

Add rows with data

movies.add_row({"Movie Name", "Director", "Release Year"});
movies.add_row({"Toy Story 4", "Josh Cooley", "2019"});
4

Print the table

std::cout << movies << std::endl;
That’s it! You’ve created your first table.

Adding Style

Now let’s make it look better with some formatting:
#include <tabulate/table.hpp>
using namespace tabulate;

int main() {
  Table movies;
  movies.add_row({"Movie Name", "Director", "Release Year"});
  movies.add_row({"Toy Story 4", "Josh Cooley", "2019"});
  movies.add_row({"Sully", "Clint Eastwood", "2016"});
  
  // Format the header row
  movies[0].format()
    .font_color(Color::yellow)
    .font_align(FontAlign::center)
    .font_style({FontStyle::bold});
  
  std::cout << movies << std::endl;
}

Using RowStream for Dynamic Data

When working with different data types, use RowStream to format values on the fly:
#include <tabulate/table.hpp>
using namespace tabulate;

int main() {
  Table employees;
  
  employees.add_row({"Emp. ID", "First Name", "Last Name", "Department", "Pay Rate"});
  
  // Use RowStream to insert various types
  employees.add_row(RowStream{} << 101 << "Donald" << "Patrick" << "Finance" << 59.62);
  employees.add_row(RowStream{} << 102 << "Rachel" << "Williams" << "Marketing" << 34.97);
  employees.add_row(RowStream{} << 103 << "Ian" << "Jacob" << "Engineering" << 57.00);
  
  std::cout << employees << std::endl;
}
RowStream automatically converts integers, floats, and other types to strings using operator<<.

Key Formatting Methods

Here are the essential formatting methods you’ll use most often:
cell.format()
  .font_style({FontStyle::bold})           // bold, italic, underline, etc.
  .font_color(Color::red)                  // 8 colors available
  .font_background_color(Color::yellow)    // background color
  .font_align(FontAlign::center);          // left, center, right
Available font styles:
  • FontStyle::bold
  • FontStyle::italic
  • FontStyle::underline
  • FontStyle::blink
  • FontStyle::dark
  • FontStyle::crossed
  • FontStyle::reverse
table.format()
  .border_top("=")
  .border_bottom("=")
  .border_left("|")
  .border_right("|")
  .corner("+");

// Or style all borders at once
table.format().border("-");

// Color borders
table.format()
  .border_color(Color::cyan)
  .corner_color(Color::magenta);
cell.format()
  .width(30)              // Set cell width
  .padding_top(1)         // Add padding
  .padding_bottom(1)
  .padding_left(2)
  .padding_right(2);
// Enable for UTF-8, emoji, CJK characters
table.format().multi_byte_characters(true);

// Or for specific cells/columns
table.column(1).format().multi_byte_characters(true);

Accessing Table Elements

Tabulate provides intuitive access to rows, columns, and cells:
Table table;
// ... add rows ...

// Access a row by index
Row& row = table[0];
row.format().font_color(Color::red);

// Access a column by index
Column col = table.column(1);
col.format().font_align(FontAlign::right);

// Access a specific cell
table[0][1].format().font_style({FontStyle::bold});

// Alternative: row then column
table.row(2).format().font_background_color(Color::blue);

Range-Based Iteration

Iterate over rows and cells easily:
// Iterate over all rows
for (auto& row : table) {
  row.format().font_style({FontStyle::bold});
}

// Iterate over cells in a row
for (auto& cell : table[0]) {
  cell.format().font_align(FontAlign::center);
}

// Iterate over cells in a column
for (auto& cell : table.column(0)) {
  cell.format().font_color(Color::yellow);
}

Complete Example

Here’s a complete, real-world example that demonstrates multiple features:
#include <iostream>
#include <tabulate/table.hpp>

using namespace tabulate;

int main() {
  Table company;

  company.add_row({"Company", "Contact", "Country"});
  company.add_row({"Alfreds Futterkiste", "Maria Anders", "Germany"});
  company.add_row({"Centro comercial Moctezuma", "Francisco Chang", "Mexico"});
  company.add_row({"Ernst Handel", "Roland Mendel", "Austria"});
  company.add_row({"Island Trading", "Helen Bennett", "UK"});
  company.add_row({"Magazzini Alimentari Riuniti", "Giovanni Rovelli", "Italy"});

  // Set column widths
  company.column(0).format().width(40);
  company.column(1).format().width(30);
  company.column(2).format().width(30);

  // Format header row
  for (auto& cell : company[0]) {
    cell.format()
      .font_style({FontStyle::underline})
      .font_align(FontAlign::center);
  }

  // Right-align first column (except header)
  size_t index = 0;
  for (auto& cell : company.column(0)) {
    if (index > 0) {
      cell.format().font_align(FontAlign::right);
    }
    index++;
  }

  // Add alternating row colors
  index = 0;
  for (auto& row : company) {
    row.format().font_style({FontStyle::bold});
    
    // Blue background for even rows (skip header)
    if (index > 0 && index % 2 == 0) {
      for (auto& cell : row) {
        cell.format().font_background_color(Color::blue);
      }
    }
    index++;
  }

  std::cout << company << std::endl;
  
  return 0;
}

Tips for Success

Start Simple

Begin with basic tables and gradually add formatting as needed.

Use the Hierarchy

Format tables for global styles, rows/columns for groups, cells for specifics.

Test Colors

Terminal color appearance varies - test with your target environment.

Explore Samples

Check out the samples/ directory for more advanced examples.
Remember: formatting cascades from table → row/column → cell. Later formatting overrides earlier settings.

Next Steps

Now that you know the basics, explore advanced features:

Formatting Options

Deep dive into all formatting capabilities

Nested Tables

Learn how to create complex layouts with nested tables

Export Formats

Export tables to Markdown and AsciiDoc

API Reference

Complete API documentation

Build docs developers (and LLMs) love