Converting HTML table to CSV file using JavaScript


HTML tables are commonly used to display tabular data on web pages. Sometimes, you may need to export this data as a CSV file so that it can be easily opened and manipulated in spreadsheet software like Excel.

To convert an HTML table to a CSV file in JavaScript, you can use the following approach:

  1. Parse the HTML table and extract its data into a JavaScript array.
  2. Convert the array into a CSV string.
  3. Create a Blob object from the CSV string.
  4. Create a download link for the Blob object.
  5. Trigger a click event on the download link to download the CSV file.

Here is an example code snippet that demonstrates this approach:

Source Code

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Table to CSV</title>
    <link rel="stylesheet" href="css/style.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css" />
  </head>
  <body>
    <div class="container">
      <table id="table">
        <thead>
          <tr>
            <th>S.No</th>
            <th>Name</th>
            <th>Age</th>
            <th>City</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>1</td>
            <td>Ram</td>
            <td>25</td>
            <td>Salem</td>
          </tr>
          <tr>
            <td>2</td>
            <td>Sam</td>
            <td>28</td>
            <td>Salem</td>
          </tr>
          <tr>
            <td>3</td>
            <td>Sara</td>
            <td>12</td>
            <td>Namakkal</td>
          </tr>
          <tr>
            <td>4</td>
            <td>Suresh Kumar</td>
            <td>22</td>
            <td>Banglore</td>
          </tr>
          <tr>
            <td>5</td>
            <td>Rakesh</td>
            <td>25</td>
            <td>Chennai</td>
          </tr>
        </tbody>
      </table>

      <button id="btnExport" type="button"><i class="fa fa-file-csv"></i> Export to CSV</button>
    </div>
    <script src="js/script.js"></script>
  </body>
</html>

js/script.js

class csvExport {
  constructor(table, header = true) {
    this.table = table;
    this.rows = Array.from(table.querySelectorAll("tr"));
    if (!header && this.rows[0].querySelectorAll("th").length) {
      this.rows.shift();
    }
    // console.log(this.rows);
    // console.log(this._longestRow());
  }

  exportCsv() {
    const lines = [];
    const ncols = this._longestRow();
    for (const row of this.rows) {
      let line = "";
      for (let i = 0; i < ncols; i++) {
        if (row.children[i] !== undefined) {
          line += csvExport.safeData(row.children[i]);
        }
        line += i !== ncols - 1 ? "," : "";
      }
      lines.push(line);
    }
    //console.log(lines);
    return lines.join("\n");
  }
  _longestRow() {
    return this.rows.reduce((length, row) => (row.childElementCount > length ? row.childElementCount : length), 0);
  }
  static safeData(td) {
    let data = td.textContent;
    //Replace all double quote to two double quotes
    data = data.replace(/"/g, `""`);
    //Replace , and \n to double quotes
    data = /[",\n"]/.test(data) ? `"${data}"` : data;
    return data;
  }
}

const btnExport = document.querySelector("#btnExport");
const tableElement = document.querySelector("#table");

btnExport.addEventListener("click", () => {
  const obj = new csvExport(tableElement);
  const csvData = obj.exportCsv();
  const blob = new Blob([csvData], { type: "text/csv" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = "file.csv";
  a.click();

  setTimeout(() => {
    URL.revokeObjectURL(url);
  }, 500);
});

This code defines a csvExport class that exports an HTML table to a CSV file.

The csvExport class constructor takes two arguments: table (the HTML table to be exported) and header (a boolean indicating whether the table has a header row or not). The constructor selects all the rows of the table and removes the header row if the header argument is false.

The exportCsv method of the csvExport class exports the table data to a CSV format. It iterates over each row of the table, iterates over each cell of the row, and appends the cell data to a CSV line. It also adds double quotes around the cell data if the data contains commas or newlines, and replaces double quotes in the cell data with two double quotes to avoid CSV formatting issues. The CSV lines are stored in an array and returned as a single string joined by newline characters.

The _longestRow method of the csvExport class returns the length of the longest row in the table.

The safeData method is a static method of the csvExport class that takes a td (table cell) element as an argument and returns the safe CSV-formatted data from the cell.

Finally, the code sets up an event listener on a "Export to CSV" button, and when the button is clicked, it creates an instance of the csvExport class with the HTML table and calls the exportCsv method to get the CSV data. It then creates a new Blob object with the CSV data, sets the object URL of the Blob as the href attribute of a dynamically created anchor element, sets the download attribute of the anchor element to "file.csv", simulates a click on the anchor element to download the file, and revokes the object URL after a 500ms delay to clean up the memory used by the Blob object.

Finally, you can add some CSS styles to enhance the look and feel of the button and container. you can adjust the CSS styles as desired to match the design of your website.

css/style.css

@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@100;300;400;500;600;700;800&display=swap");

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Poppins", sans-serif;
}

body {
  width: 100vw;
  height: 100vh;
  background-color: palegoldenrod;
  display: grid;
  place-items: center;
  color: #333;
}
.container {
  width: 600px;
  background-color: #fff;
  padding: 10px;
  border-radius: 3px;
  box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px, rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
}
table {
  width: 100%;
  border: 1px solid #a1a1a1;
  border-collapse: collapse;
}

table tr td,
table tr th {
  padding: 10px 15px;
  border: 1px solid #a1a1a1;
}
table tr th {
  background-color: #a1a1a1;
  color: aliceblue;
  font-weight: 500;
}

#btnExport {
  padding: 5px 15px;
  margin-top: 15px;
  border: none;
  background-color: green;
  color: #fff;
  border-radius: 3px;
}

Output

CSV Export

Note that this approach may not work for very large tables, as it can be memory-intensive to parse and convert the table data into a 2D array. In such cases, you may need to consider alternative approaches, such as streaming the table data or using a server-side solution.

Live Preview


List of Programs


JS Practical Questions & Answers


JS Practical Project