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

8

54

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?

Arrival answered 23/8, 2011 at 12:36 Comment(5)
How much data? Is this a one off job or will you need to run it several times?Pewter
Pretty sure you are going to have to parse the page and manually generate the csv from the data.Greige
Possibly see https://mcmap.net/q/340158/-how-do-i-convert-an-html-table-to-csv-formatCommonplace
Please find below the link to download JQuery utility which allows you to export any HTML table as CSV file. Its very handy tool to use specially during development of reporting projects. It is also useful when you have some 3rd party jQuery table search plugin attached to your table. kunalbabre.com/projects/table2CSV.phpCordwainer
Possible duplicate of Export to CSV using jQuery and htmlFari
C
28

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']})">
Colchis answered 23/8, 2011 at 12:51 Comment(5)
Hi, I really appreciate the prompt and detailed response. I tried your code but there appear to be a number of errors in the javascript. I am not a Javascript guru so I don't know how to fix it.Arrival
Thankyou. But can you please mention the errors. and also tell me did you tried the above example first?Colchis
This worked fine for me. I am using jQuery 1.7.2. Thanks very much!Mosqueda
NO love here - jquery 1.7.3 and there's nothing happening on pressing that button :(Prady
Thanks for your answer. What if my table is with pagination, and I wanna download the whole table rather than the current visiable rows? Thanks!Columbuscolumbyne
B
27

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/

Bostow answered 19/11, 2015 at 15:18 Comment(3)
Great answer. Thanks for sharing. This is exactly what I wanted!Suksukarno
Exactly what I needed! Thank youAgate
Great answer, thanks! Is there a way to specify how wide a column should be when the CSV is opened with Excel?Redwood
C
5

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>
Ceja answered 24/2, 2020 at 9:5 Comment(1)
jquery in 2020?Flagg
S
3

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")
Sheehan answered 21/8, 2012 at 22:20 Comment(0)
K
2

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
Kaiserdom answered 20/1, 2016 at 16:52 Comment(0)
P
1

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.

Pastern answered 13/12, 2014 at 19:6 Comment(0)
M
0

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.
Monoclinous answered 3/3, 2012 at 1:17 Comment(0)
D
0

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://mcmap.net/q/266726/-how-can-i-scrape-an-html-table-to-csv.

Dulaney answered 22/1, 2015 at 7:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.