Muhi Logo Text
Work With MeAboutTestimonialsBlog

How to Export HTML Table to Excel and CSV File

Learn how to export an HTML table to Excel and CSV file using JavaScript with XLSX and FileSaver libraries.

Last updated on November 26, 2023

html
javascript
html to csv

Exporting data to Excel or CSV using the browser can sometimes be challenging, especially when creating a link element and mimicking a download click.

In this tutorial, we will learn a simple approach to exporting an HTML table to Excel and CSV files using a couple of handy libraries.

Initialize Project

The project will be vanilla Javascript using Vite as a build tool.

Let’s create a new folder called “export-html-table”, navigate to it and run the following command to create a new package.json file:

npm init

A package.json file will be generated. Let’s replace it with the following:

{
  "name": "export-html-table",
  "version": "1.0.0",
  "scripts": {
    "dev": "vite"
  },
  "dependencies": {
    "file-saver": "2.0.5",
    "xlsx": "^0.18.5"
  },
  "devDependencies": {
    "vite": "^5.0.2"
  }
}

We added the dependencies for the project and configured the dev to use Vite.

Here are more details about the dependencies we added:

  • Vite: A fast build tool that significantly improves the frontend development experience.
  • file-saver: an excellent tool for saving files on the client side, especially if we generate a Blob object dynamically.
  • xlsx: A library for reading and writing Excel files.

Let’s install the dependencies by running the following command:

npm install

Lastly, we will add an index.html file and a main.js file.

Here is how the project structure should look so far:

project structure

Export HTML Table to CSV File

To export an HTML table to a CSV file, we need to read all the content of the cells and convert them to CSV format.

Let’s create a new function called exportTable in the main.js file and add the following code.

import { saveAs } from "file-saver"

export const exportTable = () => {
  const rows = document.querySelectorAll("table tr")
  let csv = []
  for (const row of rows) {
    const cells = row.querySelectorAll("td, th")
    const rowText = Array.from(cells).map(cell => cell.innerText)
    csv.push(rowText.join(","))
  }
  const csvFile = new Blob([csv.join("\n")], {
    type: "text/csv;charset=utf-8;",
  })
  saveAs(csvFile, "data.csv")
}

Here are more details of the code above:

  • Get and loop through all the rows in the table element
  • Within the loop, we are getting all the row’s cells and mapping them to a new rowText array with the innerText value
  • rowText is then converted to a text separated with a comma and pushed into the csv array (a list of all the final CSV rows)
  • Finally, we are creating a Blob file and triggering the saveAs function that downloads the CSV file

In the HTML file, we will add a basic table with some styles and a button to trigger the export function.

<!DOCTYPE html>
<html>
  <style>
    table {
      text-align: left;
      border-spacing: 0;
    }
    table th,
    td {
      border: 1px solid #ccc;
    }
  </style>
  <body>
    <button id="csvButton">Export to CSV</button>
    <table>
      <tr>
        <th>Name</th>
        <th>Position</th>
        <th>Experience</th>
      </tr>
      <tr>
        <td>John Smith</td>
        <td>Marketing</td>
        <td>5 Years</td>
      </tr>
      <tr>
        <td>Adam Kenneth</td>
        <td>Development</td>
        <td>3 Years</td>
      </tr>
      <tr>
        <td>Julia Williams</td>
        <td>HR</td>
        <td>12 Years</td>
      </tr>
    </table>
  </body>
  <script type="module">
    import { exportTable } from "./main.js"
    document
      .querySelector("#csvButton")
      .addEventListener("click", () => exportTable("csv"))
  </script>
</html>

Additionally, we are importing the exportTable function from the main.js file and adding a click event listener to the button to trigger the export function.

At this point, we can run the project using the following command:

npm run dev

And now we should be able to export the table to a CSV file.

Export HTML Table to Excel File

Exporting to an Excel file requires an additional library called “xlsx”, which we installed earlier. Let’s import it in the main.js file and update the exportTable function to support an Excel file.

import { saveAs } from "file-saver"
import * as XLSX from "xlsx"

export const exportTable = format => {
  const table = document.querySelector("table")
  const rows = document.querySelectorAll("table tr")

  if (format === "csv") {
    let csv = []
    for (const row of rows) {
      const cells = row.querySelectorAll("td, th")
      const rowText = Array.from(cells).map(cell => cell.innerText)
      csv.push(rowText.join(","))
    }
    const csvFile = new Blob([csv.join("\n")], {
      type: "text/csv;charset=utf-8;",
    })
    saveAs(csvFile, "data.csv")
  } else if (format === "excel") {
    const workbook = XLSX.utils.table_to_book(table)
    const options = { bookType: "xlsx", bookSST: false, type: "array" }
    const output = XLSX.write(workbook, options)
    saveAs(
      new Blob([output], { type: "application/octet-stream" }),
      "data.xlsx"
    )
  } else {
    throw new Error("Unsupported format")
  }
}

In the code above, we check if the format is csv or excel and execute the appropriate code. For the Excel file, we use the table_to_book function to convert the table to a workbook and then the write function to convert the workbook to an Excel file.

Now, we can update the HTML file to support the Excel export.

<!DOCTYPE html>
<html>
    <style>
        table {
            text-align: left;
            border-spacing: 0;
        }
        table th, td {
            border: 1px solid #ccc;
        }
    </style>
    <body>
        <button id="csvButton">Export to CSV</button>
        <button id="excelButton">Export to Excel</button>
        <table>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Experience</th>
            </tr>
            <tr>
                <td>John Smith</td>
                <td>Marketing</td>
                <td>5 Years</td>
            </tr>
            <tr>
                <td>Adam Kenneth</td>
                <td>Development</td>
                <td>3 Years</td>
            </tr>
            <tr>
                <td>Julia Williams</td>
                <td>HR</td>
                <td>12 Years</td>
            </tr>
        </table>
    </body>
    <script type="module">
        import { exportTable } from './main.js';
        document
          .querySelector('#csvButton')
          .addEventListener('click', () => exportTable('csv'));

        document
          .querySelector('#excelButton')
          .addEventListener('click', () => exportTable('excel'));
    </script>
</html>

And that’s it! We can now export the table to an Excel file.

Summary

In this tutorial, we learned how to export an HTML table to CSV and Excel with one function that accepts a format parameter. The project is configured with Vite and has two dependencies: file-saver and xlsx, but it’s using vanilla Javascript and doesn’t require any additional frameworks like React or Vue.

The complete code is available in this repository.

Bye for now 👋

If you enjoyed this post, I regularly share similar content on Twitter. Follow me @muhimasri to stay up to date, or feel free to message me on Twitter if you have any questions or comments. I'm always open to discussing the topics I write about!

Recommended Reading

Learn how to create a scrollable table with a sticky header and column in React.

react
html
css

Discussion

Upskill Your Frontend Development Techniques 🌟

Subscribe to stay up-to-date and receive quality front-end development tutorials straight to your inbox!

No spam, sales, or ads. Unsubscribe anytime you wish.

© 2024, Muhi Masri