How to read data from nodes and display in this complex table?
You'll have to flatten the data yourself, as you're grouping by date (you'd have to regardless of the double header and colspans), but yes, theme_table can accommodate that.

I haven't tested this but it should be at least near to working. The key points to note are colspan, which does what you'd think, and header, which will mark a cell to be rendered as &lt;th&gt; rather than &lt;td&gt;. Meaning you can stuff the second row of headers into the body. Not ideal, as they'll be inside a &lt;tbody&gt;, but I suspect good enough.

$header = [
  [
    'data' =&gt; '',
    'colspan' =&gt; 2,
  ],
  [
    'data' =&gt; 'Type',
    'colspan' =&gt; 3,
  ],
];

$rows = [
  [
    [
      'data' =&gt; 'Day',
      'header' =&gt; TRUE,
    ],
    // Other header rows here, with 'header' =&gt; TRUE
  ]
];

// Loop through your grouped data
foreach ($data as $item) {
  $rows[] = [
    $item-&gt;date,
    $item-&gt;colours,
    $item-&gt;type_a,
    $item-&gt;type_b,
    $item-&gt;type_c,
  ];
}

$build = [
  '#theme' =&gt; 'table',
  '#header' =&gt; $header,
  '#rows' =&gt; $rows,
];