Here's a loop for the Field Labels, assuming you want those as header cells above your Field Values in your table.
<tr>
{exp:query sql="Select CONCAT('field_id_',field_id) 'field_id', field_name, field_label
from exp_channel_fields f join exp_channels c on c.field_group = f.group_id
where c.channel_id = 1
order by field_order"}
<th>{field_label}</th>
{/exp:query}
</tr>
I don't think that takes into consideration Publish Layout order. I assume that's also in exp_channel_fields, but am not sure how it's stored. It does reference the Field Order you set in the field definition.
If you then looped through the entries in that channel, you might pass the entry_id for each row into a nested template that will loop through these field IDs and get each value in the same order from exp_channel_data.
Updated: Trying to query all the corresponding fields in each pass of a channel:entries loop is going to be a lot of queries. Really what you want to do is use the first query to generate a string of column names, such as:
field_id_10, field_id_11, field_id_34, field_id_35
And then build that into another SQL query:
Select field_id_10, field_id_11, field_id_34, field_id_35
from exp_channel_data d join exp_channel_titles t on d.entry_id = t.entry_id where t.channel_id = 1
order by title asc
So the first query gets your column headings and can be used to generate a matching field list. The second query gets the field data in the same order as the field list, for every entry. I can't help thinking that should reside in PHP, because then you can use something like:
<td>query_result[0]</td>
<td>query_result[1]</td>
<td>query_result[2]</td>
<td>query_result[3]</td>
Without having to know the field_id_# names. You could also iterate over the length of the results array, so you wouldn't need to know how many fields are being returned. It'd be completely data-driven.