Sample code for 30+ languages & platforms
Dart

HTML Table to CSV

See more HTML-to-XML/Text Examples

Demonstrates a method for converting an HTML table to a CSV file.

Note: This example requires Chilkat v9.5.0.77 or greater.

Chilkat Dart Downloads

Dart
import 'package:chilkat/chilkat.dart';

void main() {
  // This example requires the Chilkat API to have been previously unlocked.
  // See Global Unlock Sample for sample code.

  // First download the HTML containing the table
  final http = CkHttp();
  final bdHtml = CkBinData();

  try {
    http.quickGetBd('https://example-code.com/data/etf_table.html', bdHtml);
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  // Convert to XML.
  final htx = CkHtmlToXml();
  htx.setHtmlBd(bdHtml);

  final sbXml = CkStringBuilder();
  htx.toXmlSb(sbXml);

  final xml = CkXml();
  xml.loadSb(sbXml, true);

  // Remove attributes and sub-trees we don't need.
  // (In other words, we're getting rid of clutter...)
  var numRemoved = xml.pruneTag('thead');
  numRemoved = xml.pruneAttribute('style');
  numRemoved = xml.pruneAttribute('class');

  // Scrub the element and attribute content.
  xml.scrub('ContentTrimEnds,ContentTrimInside,AttrTrimEnds,AttrTrimInside');

  // Let's see what we have...
  print(xml.getXml());

  // We have the following XML.
  // Copy this XML into the online tool at Generate Parsing Code from XML
  // as a starting point for accessing the data..

  // <?xml version="1.0" encoding="utf-8"?>
  // <root>
  //     <html>
  //         <head>
  //             <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
  //         </head>
  //         <body text="#000000" bgcolor="#FFFFFF">
  //             <div>
  //                 <div>
  //                     <table role="grid" data-scrollx="true" data-sortdirection="desc" data-sorton="-1"/>
  //                 </div>
  //             </div>
  //             <div>
  //                 <table id="topHoldingsTable" role="grid" data-scrollx="true" data-sortdirection="desc" data-sorton="-1">
  //                     <tbody>
  //                         <tr role="row">
  //                             <td>
  //                                 <text>ITUB4</text>
  //                             </td>
  //                             <td>
  //                                 <text>ITAU UNIBANCO HOLDING PREF SA</text>
  //                             </td>
  //                             <td>
  //                                 <text>Financials</text>
  //                             </td>
  //                             <td>
  //                                 <text>Brazil</text>
  //                             </td>
  //                             <td>
  //                                 <text>10.94</text>
  //                             </td>
  //                             <td>
  //                                 <text>998,954,813.73</text>
  //                             </td>
  //                         </tr>
  //                         <tr role="row">
  //                             <td>
  //                                 <text>BBDC4</text>
  //                             </td>
  //                             <td>
  //                                 <text>BANCO BRADESCO PREF SA</text>
  //                             </td>
  //                             <td>
  //                                 <text>Financials</text>
  //                             </td>
  //                             <td>
  //                                 <text>Brazil</text>
  //                             </td>
  //                             <td>
  //                                 <text>9.01</text>
  //                             </td>
  //                             <td>
  //                                 <text>822,164,622.75</text>
  //                             </td>
  //                         </tr>
  // 			...
  // 			...
  // 			...
  //                     </tbody>
  //                 </table>
  //             </div>
  //         </body>
  //     </html>
  // </root>

  // This is the code generated by the online tool:
  // 
  var i = 0;
  var countI = 0;
  var tableRole = '';
  var tableDataScrollx = '';
  var tableDataSortdirection = '';
  var tableDataSorton = '';
  var tableId = '';
  var j = 0;
  var countJ = 0;
  var trRole = '';
  var k = 0;
  var countK = 0;
  final tagPath = '';
  var text = '';

  i = 0;
  countI = xml.numChildrenHavingTag('html|body|div');
  while (i < countI) {
    xml.i = i;
    tableRole = xml.chilkatPath('html|body|div[i]|div|table|(role)');
    tableDataScrollx = xml.chilkatPath('html|body|div[i]|div|table|(data-scrollx)');
    tableDataSortdirection = xml.chilkatPath('html|body|div[i]|div|table|(data-sortdirection)');
    tableDataSorton = xml.chilkatPath('html|body|div[i]|div|table|(data-sorton)');
    tableId = xml.chilkatPath('html|body|div[i]|table|(id)');
    tableRole = xml.chilkatPath('html|body|div[i]|table|(role)');
    tableDataScrollx = xml.chilkatPath('html|body|div[i]|table|(data-scrollx)');
    tableDataSortdirection = xml.chilkatPath('html|body|div[i]|table|(data-sortdirection)');
    tableDataSorton = xml.chilkatPath('html|body|div[i]|table|(data-sorton)');
    j = 0;
    countJ = xml.numChildrenHavingTag('html|body|div[i]|table|tbody|tr');
    while (j < countJ) {
      xml.j = j;
      trRole = xml.chilkatPath('html|body|div[i]|table|tbody|tr[j]|(role)');
      k = 0;
      countK = xml.numChildrenHavingTag('html|body|div[i]|table|tbody|tr[j]|td');
      while (k < countK) {
        xml.k = k;
        text = xml.getChildContent('html|body|div[i]|table|tbody|tr[j]|td[k]|text');
        k++;
      }

      j++;
    }

    i++;
  }

  // Let's modify the above code to build the CSV.
  final csv = CkCsv();
  csv.setColumnName(0, 'Ticker');
  csv.setColumnName(1, 'Name');
  csv.setColumnName(2, 'Sector');
  csv.setColumnName(3, 'Country');
  csv.setColumnName(4, 'Weight');
  csv.setColumnName(5, 'Notional Vaue');

  i = 0;
  countI = xml.numChildrenHavingTag('html|body|div');
  while (i < countI) {
    xml.i = i;
    j = 0;
    countJ = xml.numChildrenHavingTag('html|body|div[i]|table|tbody|tr');
    while (j < countJ) {
      xml.j = j;
      k = 0;
      countK = xml.numChildrenHavingTag('html|body|div[i]|table|tbody|tr[j]|td');
      while (k < countK) {
        xml.k = k;
        csv.setCell(j, k, xml.getChildContent('html|body|div[i]|table|tbody|tr[j]|td[k]|text'));
        k++;
      }

      j++;
    }

    i++;
  }

  csv.saveFile('qa_output/brasil_etf.csv');
  final csvStr = csv.saveToString();
  print(csvStr);

  // Our CSV looks like this:
  // Ticker,Name,Sector,Country,Weight,Notional Vaue
  // ITUB4,ITAU UNIBANCO HOLDING PREF SA,Financials,Brazil,10.94,"998,954,813.73"
  // BBDC4,BANCO BRADESCO PREF SA,Financials,Brazil,9.01,"822,164,622.75"
  // VALE3,CIA VALE DO RIO DOCE SH,Materials,Brazil,8.60,"785,290,260.07"
  // PETR4,PETROLEO BRASILEIRO PREF SA,Energy,Brazil,5.68,"518,124,434.10"
  // PETR3,PETROBRAS,Energy,Brazil,4.86,"443,254,438.53"
  // B3SA3,B3 BRASIL BOLSA BALCAO SA,Financials,Brazil,4.57,"417,636,740.16"
  // ABEV3,AMBEV SA,Consumer Staples,Brazil,4.57,"417,216,913.63"
  // BBAS3,BANCO DO BRASIL SA,Financials,Brazil,3.25,"296,921,232.15"
  // ITSA4,ITAUSA INVESTIMENTOS ITAU PREF SA,Financials,Brazil,2.90,"265,153,684.52"
  // LREN3,LOJAS RENNER SA,Consumer Discretionary,Brazil,2.25,"205,832,175.98"
  // 
}