Instant and dynamic HTML table creation with JavaScript
Last updated: February 10, 2022.
Do you find hard-coding HTML tables tedious? The good news is you can spare yourself this effort by creating tables dynamically using JavaScript.
To start using the table generator function, copy and paste the code below into your project and call the function according to the usage notes.
Build notes that may be helpful to you in creating your own table generator function or customizing the one provided here are contained in notes alongside the code.
Using the JavaScript table generator function
Usage notes
tableCreate(rows, cols, thead, tfoot)
rows: table rows (numeric)cols: table columns (numeric)thead: head title (string) or column titles (array)tfoot: foot title (string)
The return value of the function is the table. So it can be rendered to the DOM like this:
<body>
<! --- Some DOM content --->
<div id="table"></div>
<! --- More DOM content --->
<script>
document.getElementById('table').innerHTML = tableCreate(rows, cols, thead, tfoot)
</script>
</body>
Output examples
Example 1: Simple table
A simple table with a heading and five rows of data:
const data = ["United States","China","India","Russia","Germany"]; tableCreate(5,1, "Five large countries", "By JavaScript");

Example 2: Meal plan
A more complex table with multiple rows and columns as well as column titles.
The cells in the first column of the table have the class attribute col-left and so can be separately styled in CSS:
// Define data input
const data = ["Monday", "Cereal", "Steamed rice", "Baked Potatoes",
"Tuesday", "Bagel", "Spaghetti bolognese", "Pasta salad",
"Wednesday", "Oatmeal", "Pasta", "Burger",
"Thursday", "Cereal", "Fish and chips", "Fried Rice",
"Friday", "Fried breakfast", "Sandwiches", "Lasange"
]
// Define headings
const headings = ['', 'Breakfast', 'Lunch', 'Dinner']
/* Call tableCreate */
tableCreate(5,4,data,headings,'Created by JavaScript');

The code
Table generator function:
/* Defining the tableCreate function */
function tableCreate(rows, cols, data, thead, tfoot) {
// 1) Create table and body elements
let table = document.createElement('table')
let tableBody = document.createElement('tbody')
// 2) Optional header
let headContent = document.createElement('thead')
let tr = document.createElement('tr')
// 2.1) Sets default behavior: Single cell header
if (thead && Array.isArray(thead) == false) {
let td = document.createElement('td')
td.innerHTML = thead // Set header text to argument input
td.setAttribute('colspan', cols) // Span header for as many cols as table
tr.append(td)
headContent.append(tr) // append head row to thead element
thead = headContent // Make this final value of thead
}
// 2.2) If "split" is third argument: Creates a multi-cell header
if (Array.isArray(thead)) {
let i
for (i = 0; i < cols; i++) {
let td = document.createElement('td')
td.id = 'thead' + i
td.innerHTML = thead[i]
tr.append(td) // append multiple td to head row
}
headContent.append(tr) // append head row to thead element
thead = headContent // Make this final value of thead
}
// 3) Optional footer (text is user input string)
if (tfoot) {
footElement = document.createElement('tfoot')
tr = document.createElement('tr')
td = document.createElement('td')
td.innerHTML = tfoot // Set text to fourth argument input
td.setAttribute('colspan', cols)
tr.append(td) // Append single cell to row
footElement.append(tr) // Append row to tfoot element
tfoot = footElement // Make this final value of tfoot
}
// 4) Create table body rows and cell with loops
let i
for (i = 0; i < rows; i++) {
// Loop to create row
let tr = document.createElement('tr')
let id = i * cols // Nested loop to append cells to rows (first loop id = 0*5; second loop id = 1*5, etc)
for (j = 0; j < cols; j++) {
let td = document.createElement('td')
id++ // increase id by 1 (first loop is 0+1 = 1)
if (id == i * cols + 1) {
td.classList.add('left-col')
}
td.innerHTML = id // print id in col cell
td.setAttribute('id', 'cell' + id) // set id of element to id
tr.append(td) // append col cell to table row
// Repeats until j < column numbers entered by user
if (data) {
td.innerHTML = data[id - 1]
}
}
tableBody.append(tr)
}
// 5) Append head, body and footer
if (thead) {
table.append(thead)
}
table.append(tableBody)
if (tfoot) {
table.append(tfoot)
}
// Show table in console
console.log(table)
// 6) Return a value for the function
return table
}
CSS styling
/* import custom Open Sans font */
@import url('https://fonts.googleapis.com/css2?family=Open+Sans&display=swap');
body {
background: linear-gradient(#e66465, #9198e5);
background-repeat: no-repeat;
background-position: top left;
height: 100vh;
margin: 0px;
}
#table {
display: flex;
justify-content: center;
margin-top: 3rem;
}
table {
font-family: 'Open Sans', sans-serif;
border-collapse: collapse;
color: black;
}
thead {
background-color: lightblue;
font-weight: bold;
border-bottom: 2px solid white;
}
th, td {
padding: 0.5rem;
padding-left: 3rem;
padding-right: 3rem;
text-align: center;
}
tbody tr td {
padding: 0.5rem;
padding-left: 0.8rem;
padding-right: 0.8rem;
}
/* Even row styling */
tbody tr:nth-child(even) {
background-color: #f2f2f2;
}
/* Odd row styling */
tbody tr:nth-child(odd) {
background-color: white;
}
/* Left column styling */
.col-left {
background-color: lightblue;
color: black;
font-weight: 400;
border-top: 2px solid white;
border-bottom: 2px solid white;
}
tfoot {
background-color: rgb(206, 231, 240);
font-size: 0.7rem;
padding: 0.1rem;
border-top: 2px solid white;
}
tfoot tr td {
padding: 0.2rem;
text-align: right;
}





