You may need to add some single quotes and a sequence to preserve the order:

set pages 0 head off recsep off lin 132 feed off term off
col sq noprint
spo cross.sql
select 0000 sq,'select ID' from dual
union
select rownum sq,',sum(decode(type,'''||type||''',area,0)) '||type
from (select distinct type from CROSS)
union
select rownum+1000 sq,',sum(decode(category,'''||category||''',area,0)) '||category
from (select distinct category from CROSS)
union
select 9999 sq,'from CROSS group by id;' from dual
order by 1
/
spo off
set pages 55 head on recsep on lin 80 feed on term on
@cross.sql