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; }