Por el código, veo que haces lo tradicional: primero generas el archivo XLS en disco, y luego lo abres para enviarlo al navegador web. De ese código, lo que falta por hacer es un $workbook->
close() para que el módulo grabe todos los cambios a disco.
Pero, te repito, que no necesitas hacerlo de esa manera.
Puedes generar el archivo XLS en
memoria, y no tener que grabarlo en disco. Solo tienes que 1) enviar las cabeceras, y 2) crear el objeto Spreadsheet::WriteExcel con destino la salida estándar. Así:
Using perl Syntax Highlighting
print "Content-type: application/vnd.ms-excel\n";
# The Content-Disposition will generate a prompt to save the file. If you want
# to stream the file to the browser, comment out the following line.
print "Content-Disposition: attachment; filename=$filename\n";
print "\n";
# Create a new workbook and add a worksheet. The special Perl filehandle - will
# redirect the output to STDOUT
#
my $workbook = Spreadsheet::WriteExcel->new(\*STDOUT);
Coloreado en 0.003 segundos, usando
GeSHi 1.0.8.4
(Líneas extraídas del ejemplo
cgi.pl de la página
Spreadsheet::WriteExcel::Examples)
De todas maneras, si quieres grabar el resultado a disco, entonces puedes hacerlo como hasta ahora, pero poniendo el close().
Fíjate en lo que pone en los comentarios: el envío de la cabecera 'attachment' provoca que, al usuario, le aparezca el formulario de "Guardar como...", para que elija nombre y destino del archivo que está recibiendo. ¿Es ese el comportamiento que quieres que ocurra? Como hablas de la "apertura automática", entendí que te referías a que se ejecutara el Excel con ese archivo.
Otro caso, que acabo de darme cuenta. ¿Estás generando los archivos en la misma máquina en donde los quieres ver?