A PL/SQL package can create an excel output, using the following technique:
In your package APPS.XXMY_PKG, procedure HTML_OUTPUT:
if n_is_excel = 1 then
--Set headers to create excel
OWA_UTIL.MIME_HEADER('application/ms-excel;', FALSE);
HTP.P('content-disposition: filename="MyReport_' || to_char (sysdate,'RRRRMMDD_HH24MISS') || '.xls"');
OWA_UTIL.HTTP_HEADER_CLOSE;
end if;
HTP.P('<html>custom report</html>);
In APEX button:
/pls/apex/APPS.XXMY_PKG.HTML_OUTPUT?P_APP_SESSION=&APP_SESSION.&P_CURR_SYSDATE=&P_SYSDATE.&
P_APP_USER=&APP_USER.&N_IS_EXCEL=1
You need also to run the following statement, otherwise the package can not be called:
grant execute on APPS.XXMY_PKG to apex_public_user;