I'm not sure I see why you're building the $line array using the index $i * $skey, though I'm no PHP expert. It seems as if you create an array called $line, then for each individual field you create a new entry in that array. Shouldn't $i be the line number, so you'd be either setting $line[$i] = "$temp[added]" and so on, or $line[$i] .= "$mess[$skey]" ?
foreach ($new as $skey=>$value)
if ( !(empty($value['type'])) && !($value['type']=='captcha'))
$mess[$skey] = "$value[value]";
$line[$i] = "$temp[added]\ $temp[form_id]\ $mess[$skey]";
$line[$i] .= "\ $mess[$skey]";
} // End of foreach (field loop)
Although to make the columns line up you'd have to do something about adding a tab when the field is empty, rather than just ignore it in the start of the loop. And I'm not sure what the data looks like, so it's hard to say properly.
And, wouldn't it be better to give it a ".csv" extension rather than ".xls", as it's not a proper xls binary file? I can see you can open it, so perhaps it doesn't matter too much.