forrest
forrest

Reputation: 10972

How do I export html table data as .csv file?

I have a table of data in an html table on a website and need to know how to export that data as .csv file.

How would this be done?

Upvotes: 55

Views: 202389

Answers (9)

Muhammad Waqas Iqbal
Muhammad Waqas Iqbal

Reputation: 3344

Below is pure js and html based solution, it converts the html to csv and exports the file

function downloadCSV() {

                // Getting values of current time for generating the file name, with current date and time
                const dateTime = new Date();
                const day = dateTime.getDate();
                const month = dateTime.getMonth() + 1;
                const year = dateTime.getFullYear();
                const hour = dateTime.getHours();
                const minute = dateTime.getMinutes();
                const postfix = `${day}.${month}.${year}_${hour}.${minute}`;

                //get the table by its id
                const table = document.getElementById('shiftTable');
                let csvContent = '';
                //traverse the table rows and create csv contents
                for (let i = 0; i < table.rows.length; i++) {
                    let row = table.rows[i];
                    let rowData = [];
                    //traverse the table columns and create comma separeted columns
                    for (let j = 0; j < row.cells.length; j++) {
                        let cell = row.cells[j];
                        //don't include the columns which have 'ignore-column' attribute, in case some column need to be removed from csv
                        if (cell.attributes.getNamedItem('ignore-column') == null) {
                            rowData.push(cell.textContent.replace(/,/g, ''));
                        }
                    }
                    //add line feed to complete a row
                    csvContent += rowData.join(',') + '\r\n';
                }
                //xreatea a blob with csv contents
                const blob = new Blob([csvContent], { type: 'text/csv' });
                //create a url to link to csv content blob
                const url = URL.createObjectURL(blob);
                //create anchor to point to url
                const a = document.createElement('a');
                a.href = url;
                //download the file with date time in name
                a.download = `shifts_${postfix}.csv`;
                //add the anchor to document, so it can be clicked
                document.body.appendChild(a);
                //call the click event, so the csv contents can be downloadws
                a.click();
                //remove the anchor as its purpose is served
                document.body.removeChild(a);

            }
  <button class="mt-1 btn btn-complete btn-cons btnGo" onclick="downloadCSV()">Export</button>
<table class="table" :class="loading ? 'loading' : ''" id="shiftTable">
            <thead>
                <tr>
                    <th><span>Employee</span></th>
                    <th><span>Clocked In</span></th>
                    <th><span>Clocked Out</span></th>
                    <th><span >Duration</th>
                    <th ignore-column="true">Action</th>
                </tr>
            </thead>
            <tbody>
<tr><td>Khurram</td> <td>Tue Oct 08 2024 12:11:00 p.m.</td> <td>Sun Oct 13 2024 8:22:00 p.m.</td> <td>8 hr(s), 11 min(s)</td> <td ignore-column="true"><a href="/Shift/10HYAGKNRFSX2">View</a></td></tr>
              <tr><td>Khurram</td> <td>Thu Oct 03 2024 9:12:00 p.m.</td> <td>Thu Oct 03 2024 9:13:00 p.m.</td> <td>0 hr(s), 1 min(s)</td> <td ignore-column="true"><a href="/Shift/WZXZH7AKXBWP8">View</a></td></tr>
            </tbody>
        </table>

to ignore any column (sometimes we have more columns in display which are useless for csv), add "ignore-column" attribute to it (see html) enter image description here

to verify the csv file contents, you can use the link https://www.convertcsv.com/csv-viewer-editor.htm

to view the running code with downloadable csv file you can click https://codepen.io/mwaqasiqbal/pen/poMrpVE

Upvotes: 0

dabeng
dabeng

Reputation: 1450

The following solution can do it.

$(function() {
  $("button").on('click', function() {
    var data = "";
    var tableData = [];
    var rows = $("table tr");
    rows.each(function(index, row) {
      var rowData = [];
      $(row).find("th, td").each(function(index, column) {
        rowData.push(column.innerText);
      });
      tableData.push(rowData.join(","));
    });
    data += tableData.join("\n");
    $(document.body).append('<a id="download-link" download="data.csv" href=' + URL.createObjectURL(new Blob([data], {
      type: "text/csv"
    })) + '/>');


    $('#download-link')[0].click();
    $('#download-link').remove();
  });
});
table {
  border-collapse: collapse;
}

td,
th {
  border: 1px solid #aaa;
  padding: 0.5rem;
  text-align: left;
}

td {
  font-size: 0.875rem;
}

.btn-group {
  padding: 1rem 0;
}

button {
  background-color: #fff;
  border: 1px solid #000;
  margin-top: 0.5rem;
  border-radius: 3px;
  padding: 0.5rem 1rem;
  font-size: 1rem;
}

button:hover {
  cursor: pointer;
  background-color: #000;
  color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Author</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>jQuery</td>
      <td>John Resig</td>
      <td>The Write Less, Do More, JavaScript Library.</td>
    </tr>
    <tr>
      <td>React</td>
      <td>Jordan Walke</td>
      <td>React makes it painless to create interactive UIs.</td>
    </tr>
    <tr>
      <td>Vue.js</td>
      <td>Yuxi You</td>
      <td>The Progressive JavaScript Framework.</td>
    </tr>
  </tbody>
</table>

<div class="btn-group">
  <button>csv</button>
</div>

Upvotes: 5

talha2k
talha2k

Reputation: 25650

For exporting html to csv try following this example. More details and examples are available at the author's website.

Create a html2csv.js file and put the following code in it.

jQuery.fn.table2CSV = function(options) {
    var options = jQuery.extend({
        separator: ',',
        header: [],
        delivery: 'popup' // popup, value
    },
    options);

    var csvData = [];
    var headerArr = [];
    var el = this;

    //header
    var numCols = options.header.length;
    var tmpRow = []; // construct header avalible array

    if (numCols > 0) {
        for (var i = 0; i < numCols; i++) {
            tmpRow[tmpRow.length] = formatData(options.header[i]);
        }
    } else {
        $(el).filter(':visible').find('th').each(function() {
            if ($(this).css('display') != 'none') tmpRow[tmpRow.length] = formatData($(this).html());
        });
    }

    row2CSV(tmpRow);

    // actual data
    $(el).find('tr').each(function() {
        var tmpRow = [];
        $(this).filter(':visible').find('td').each(function() {
            if ($(this).css('display') != 'none') tmpRow[tmpRow.length] = formatData($(this).html());
        });
        row2CSV(tmpRow);
    });
    if (options.delivery == 'popup') {
        var mydata = csvData.join('\n');
        return popup(mydata);
    } else {
        var mydata = csvData.join('\n');
        return mydata;
    }

    function row2CSV(tmpRow) {
        var tmp = tmpRow.join('') // to remove any blank rows
        // alert(tmp);
        if (tmpRow.length > 0 && tmp != '') {
            var mystr = tmpRow.join(options.separator);
            csvData[csvData.length] = mystr;
        }
    }
    function formatData(input) {
        // replace " with “
        var regexp = new RegExp(/["]/g);
        var output = input.replace(regexp, "“");
        //HTML
        var regexp = new RegExp(/\<[^\<]+\>/g);
        var output = output.replace(regexp, "");
        if (output == "") return '';
        return '"' + output + '"';
    }
    function popup(data) {
        var generator = window.open('', 'csv', 'height=400,width=600');
        generator.document.write('<html><head><title>CSV</title>');
        generator.document.write('</head><body >');
        generator.document.write('<textArea cols=70 rows=15 wrap="off" >');
        generator.document.write(data);
        generator.document.write('</textArea>');
        generator.document.write('</body></html>');
        generator.document.close();
        return true;
    }
};

include the js files into the html page like this:

<script type="text/javascript" src="jquery-1.3.2.js" ></script>

<script type="text/javascript" src="html2CSV.js" ></script>

TABLE:

<table id="example1" border="1"  style="background-color:#FFFFCC" width="0%" cellpadding="3" cellspacing="3">

    <tr>

        <th>Title</th>

        <th>Name</th>

        <th>Phone</th>

    </tr>

    <tr>

        <td>Mr.</td>

        <td>John</td>

        <td>07868785831</td>

    </tr>

    <tr>

        <td>Miss</td>

        <td><i>Linda</i></td>

        <td>0141-2244-5566</td>

    </tr>

    <tr>

        <td>Master</td>

        <td>Jack</td>

        <td>0142-1212-1234</td>

    </tr>

    <tr>

        <td>Mr.</td>

        <td>Bush</td>

        <td>911-911-911</td>

    </tr>

</table>

EXPORT BUTTON:

<input value="Export as CSV 2" type="button" onclick="$('#example1').table2CSV({header:['prefix','Employee Name','Contact']})">

Upvotes: 28

Roozbeh Zabihollahi
Roozbeh Zabihollahi

Reputation: 7347

Thanks to gene tsai, here is some modifications to his code to run on my target page:

csv = []
rows = $('#data tr');
for(i =0;i < rows.length;i++) {
    cells = $(rows[i]).find('td,th');
    csv_row = [];
    for (j=0;j<cells.length;j++) {
        txt = cells[j].innerText;
        csv_row.push(txt.replace(",", "-"));
    }
    csv.push(csv_row.join(","));
}
output = csv.join("\n")

improvements:

  • Use generic JavaScript for loop
  • make sure each cell does not have a comma

Upvotes: 2

Michael Singer
Michael Singer

Reputation: 442

I was able to use the answer outlined here: Export to CSV using jQuery and html and added in a modification to make it work in IE and another modification mentioned in the comments to grab the thead from the table.

function exportTableToCSV($table, filename) {

    var $rows = $table.find('tr:has(td),tr:has(th)'),

        // Temporary delimiter characters unlikely to be typed by keyboard
        // This is to avoid accidentally splitting the actual contents
        tmpColDelim = String.fromCharCode(11), // vertical tab character
        tmpRowDelim = String.fromCharCode(0), // null character

        // actual delimiter characters for CSV format
        colDelim = '","',
        rowDelim = '"\r\n"',

        // Grab text from table into CSV formatted string
        csv = '"' + $rows.map(function (i, row) {
            var $row = $(row), $cols = $row.find('td,th');

            return $cols.map(function (j, col) {
                var $col = $(col), text = $col.text();

                return text.replace(/"/g, '""'); // escape double quotes

            }).get().join(tmpColDelim);

        }).get().join(tmpRowDelim)
            .split(tmpRowDelim).join(rowDelim)
            .split(tmpColDelim).join(colDelim) + '"',



        // Data URI
        csvData = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csv);

        console.log(csv);

        if (window.navigator.msSaveBlob) { // IE 10+
            //alert('IE' + csv);
            window.navigator.msSaveOrOpenBlob(new Blob([csv], {type: "text/plain;charset=utf-8;"}), "csvname.csv")
        } 
        else {
            $(this).attr({ 'download': filename, 'href': csvData, 'target': '_blank' }); 
        }
}

// This must be a hyperlink
$("#xx").on('click', function (event) {

    exportTableToCSV.apply(this, [$('#projectSpreadsheet'), 'export.csv']);

    // IF CSV, don't do event.preventDefault() or return false
    // We actually need this to be a typical hyperlink
});

With my link looking like this...

<a href="#" id="xx" style="text-decoration:none;color:#000;background-color:#ddd;border:1px solid #ccc;padding:8px;">Export Table data into Excel</a>

JsFiddle: https://jsfiddle.net/mnsinger/65hqxygo/

Upvotes: 27

n8henrie
n8henrie

Reputation: 2955

I've briefly covered a simple way to do this with Google Spreadsheets (importHTML) and in Python (Pandas read_html and to_csv) as well as an example Python script in my SO answer here: https://stackoverflow.com/a/28083469/1588795.

Upvotes: 0

Jasty
Jasty

Reputation: 11

You could use an extension for Chrome, that works well the times I have tried it.

https://chrome.google.com/webstore/search/html%20table%20to%20csv?_category=extensions

When installed and on any web page with a table if you click on this extension's icon it shows all the tables in the page, highlighting each as you roll over the tables it lists, clicking allows you to copy it to the clipboard or save it to a Google Doc.

It works perfectly for what I need, which is occasional conversion of web based tabular data into a spreadsheet I can work with.

Upvotes: 1

gene tsai
gene tsai

Reputation: 83

Here is a really quick CoffeeScript/jQuery example

csv = []
for row in $('#sometable tr')
  csv.push ("\"#{col.innerText}\"" for col in $(row).find('td,th')).join(',')
output = csv.join("\n")

Upvotes: 3

dat
dat

Reputation: 1710

If it's an infrequent need, try one of several firefox addons which facilitate copying HTML table data to the clipboard (e.g., https://addons.mozilla.org/en-US/firefox/addon/dafizilla-table2clipboard/). For example, for the 'table2clipboard' add-on:

  1. install the add-on in firefox
  2. open the web-page (with the table) in firefox
  3. right-click anywhere in the table and select 'copy whole table'
  4. start up a spreadsheet application such as LibreOffice Calc
  5. paste into the spreadsheet (select appropriate separator character as needed)
  6. save/export the spreadsheet as CSV.

Upvotes: 0

Related Questions