Que tal, yo tenía la misma problematica, necesitaba generar la consulta en XLS, que la almacenara y luego la enviara por correo, ok... lo primero era que usaba los headers al igual que tu, eso solo sirve para que mande los resultados al navegador, lo cual pues no se si realmente lo necesites, yo se lo quite, en ves de eso puse toda mi consulta en una sola variable y al final use este codigo:
file_put_contents('MiExcel.xls',utf8_decode($cuerp o));
esto guarda un archivo llamado MiExcel.xls en la carpeta donde anda mi archivo, el contenido que lleva el mismo lo trae la variable $cuerpo, el utf8_decode/encode sirve para que me reconozca los acentos las Ñ y todos esos cáracteres que tenemos en el español. espero te sirva esto, saludos