Convert HTML table to CSV format while retaining merged rows and columns

I have a complex HTML table with rows and columns spanning different sections. I am looking for a way to export this table to a CSV file with just a click of a button.https://i.sstatic.net/OOPgg.png

Here is the code snippet for the table,

<table class="table table-bordered">
<thead class="thead-dark">
  <tr>
     <th scope="col">Fruit Name</th>
     <th scope="col">Type</th>
     <th scope="col" colspan="3">Features</th>
     <th scope="col">Recommended Values</th>
  </tr>
</thead>
<tbody ng-repeat="x in response">
  <tr>
     <th  rowspan="6"><b>{{x.FruitName}}</b></th>
     <td rowspan="6"><b>{{x.FruitType}}</b></td>
     <td rowspan="3">Color</td>
     <td>Outer </td>
     <td><b>{{x.Outer}}</b></td>
     <td>Green/Black</td>
  </tr>
  <tr>
     <td>Inner</td>
     <td><b>{{x.Inner}}</b></td>
     <td>Red</td>
  </tr>
   ... (remaining table content)
</tbody>

I attempted to use the following JavaScript function to convert the table into a CSV file on button click,

function exportTableToCSV(filename) {
        var csv = [];
        var rows = document.querySelectorAll("table tr");

        for (var i = 0; i < rows.length; i++) {
            var row = [], cols = rows[i].querySelectorAll("td, th");

            for (var j = 0; j < cols.length; j++) 
                row.push(cols[j].innerText);

            csv.push(row.join(","));        
        }
        downloadCSV(csv.join("\n"), filename);
    }
    function downloadCSV(csv, filename) {
        var csvFile;
        var downloadLink;
        csvFile = new Blob([csv], {type: "text/csv"});
        downloadLink = document.createElement("a");
        downloadLink.download = filename;
        downloadLink.href = window.URL.createObjectURL(csvFile);
        downloadLink.style.display = "none";
        document.body.appendChild(downloadLink);
        downloadLink.click();
    }

However, the output does not match what I expected based on the image provided. What would be the best approach to accurately import an HTML table into a CSV file while preserving all row and column spans? PS: Additional spanned rows and columns may need to be accommodated.

Answer №1

After testing your code, I can confirm that it works perfectly fine. I came across a helpful resource that utilizes the same method to convert tables. Despite any initial doubts you may have, this process is actually quite standard.

The resulting CSV file displays data in the following format:

Fruit Name,Type,Feature,Recommended
Watermelon,melon,Color,Outer,Green,Black/Green
Inner,Red,Red
Seed,Black,Seedless
Water,Sweet,50%,80%
Sour,20%,10%
Weight,Body Wt,400gm,500gm

You'll notice that the second row in the first cell spans six rows. In the CSV representation, the expanded content of the larger row does not shift down to subsequent rows since it's already accounted for within the same cell.

It's worth noting that even Excel handles table exports in a similar manner, where rowspan and colspan attributes are not preserved in CSV files, potentially leading to some loss of data during conversion.

In addition, I stumbled upon an informative response that provides comprehensive insights on this topic.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What exactly does the combination of {on, attrs} create within Vue/Vuetify?

Although this question may have been asked before, I am still struggling to grasp its meaning. Can you help me understand it better? <v-dialog v-model="dialog" width="500" > <template v-slot:activator=&quo ...

Modify the appearance of the elements dynamically by applying styles from the CSS file without relying on the

In my CSS file, I have the following styles: .myClass { ... } .myClass:focus { ... } Am I able to modify these styles from my code? For instance, can I change the focused style of an input element when a button is pressed? ...

What is the best way to add a listener for a modification of innerHTML within a <span>?

How can I detect changes inside a particular <span> element in order to attach a handler, but so far have been unsuccessful? Below is the HTML snippet: <span class="pad-truck-number-position"><?php echo $_SESSION['truckId']; ?> ...

adjustBounds and expand - appearing in an entirely new location

var classBounds = new google.maps.LatLngBounds(); var query = ""; query = "SELECT 'ROAD_NUMBER', 'geometry' FROM [TABLE_REFERENCE_ID] WHERE 'ROAD_NUMBER' CONTAINS IGNORING CASE '" + searchString + "' AND 'LINK_ ...

Concentrate on Managing Text Input Fields in Zend Form

I designed a form using Zend Form and want the focus to be on a text area within the form when the page loads. I attempted to use JavaScript for this purpose, but it only briefly shows the focus before removing it again, preventing any typing. I considere ...

What is the best way to create space between my cards within responsive bootstrap rows on smaller devices?

As a beginner, I welcome even the simplest advice. In this section, there is a generous amount of padding defined in bootstrap as padding-right and padding-left. When I reduce the display size, one card moves below and there is no spacing between the two ...

Guide on positioning a fixed-bottom footer in bootstrap 4 underneath the content of the page

In my Bootstrap 4 project, I am utilizing the fixed-bottom class to ensure that the footer remains at the bottom of the page when there is minimal content or the content does not fill up the entire page. Here is the CSS code for the fixed-bottom class in B ...

Completion of the form within the Bootstrap popover

I have a feature where dynamically created rows contain an "add" button. When the user clicks on the add button, a form is loaded into a Bootstrap popover. See FIDDLE DEMO My issue is: Why isn't this code being triggered? I am trying to validate ...

Initiate a CSS animation by defining a series of keyframes, followed by seamlessly transitioning into another set of keyframes to

Is it possible to create an animation that starts with one CSS keyframe set and then transitions into looping another keyframe set indefinitely? ...

Uncovering unseen glitches while coding in Vue.js

After changing the page, I noticed that the errors from the form are still visible. Is there a way to make them disappear when navigating away and only show up if I return to the page? Here are the errors I am encountering: <template> <b-form @ ...

What is the process for including an extra track in Twilio Video?

Since updating the twilio-video JS SDK from version 1.x to 2.x, I've encountered an issue when trying to add an additional device. An example of the error message is as follows: ERROR TypeError: transceiver.sender.replaceTrack(...).then(...).finally i ...

Creating an interactive R Shiny application with custom CSS styling and a modal

I am encountering an issue when trying to incorporate a modal dialog with a specific CSS style within a R Shiny app. Individually, I can successfully implement a modal dialog without the CSS style and apply the CSS style without any issues. However, when a ...

What is the best way to create a line break in a flex div container to ensure that overflowing items wrap onto the next line using

Using material-ui popper to display a list of avatars. Trying to arrange the avatars horizontally within the popper. <Popper style={{ display: 'flex', maxWidth: '200px', }}> <div style={{ marginRight: '20px' }}&g ...

Achieving Perfect Alignment in HTML Tables

I have created a simple HTML table and I am trying to center it vertically in the middle of the page based on the user's device height. So far, I have tried adding a div with 100% height and width, positioning the table at 50% from the top and left, b ...

Unable to hear sound properly through Web Audio

I'm experimenting with playing a wav file using the AudioContext. I've noticed that it plays correctly when loaded with the <audio> tag (as demonstrated in this example on jsFiddle), but encounters issues when using AudioContext. var startB ...

Is the function added using Restangular's extendModel method not working properly?

I am facing an issue with a service and controller setup. Here is my service code: .factory('Car', function(Restangular) { var baseCars = Restangular.all('cars'); Restangular.extendModel('cars', function(obj) { ...

Incorporate real-time calculations using JavaScript (jQuery) with variables including initialization in HTML code

As a newcomer to JavaScript, I am encountering an issue that I need help with: I would like to convert the value in the number box into the answer next to it without any changes to the value. This should also include the variables NP0, NP1, and DP0 from t ...

Switching between three div elements along with two icons can be done by using toggle functionality

Is there a way to make the icon change back when clicked again without making major changes to the existing code? Looking for suggestions on how to achieve this functionality. function myFunction() { var element = document.getElementById("demo"); el ...

Convert the MySQL DATE column from numerical month to full month name

I'm having trouble figuring out a simple solution. I'm using the code below to generate a tree grid from a MySQL database. $sql2 = mysql_query("SELECT DISTINCT YEAR(date) FROM blogs ORDER by YEAR(date) desc")or die(mysql_error()); $archive .= "& ...

Encountering a 422 ERROR while attempting to send a POST request

Below is the code snippet I am currently using: const url = new URL("https://api.chec.io/v1/products"); const headers = { "X-Authorization": `${process.env.NEXT_PUBLIC_CHEC_PUBLIC_KEY_SECRET}`, "Accept": "appl ...