Export oracle sql output to excel format

Export oracle sql output to excel format

Description

Hi every one, today I got a requirement that is export oracle sql output to excel format. I googled it around an one hour to get the expected and most case I got exporting the oracle query result into CSV and some other but not to excel. I finally I got a very easy and stable solution from oracle community. Here is the solution and steps you need to understand. Before starting into the detailed explanation I would like to tell you some thing please do not get scared by see the huge code. There is nothing complex here.

Steps :

1) The bellow code is a set predefined functions so we just need to call a function run_query(p_sql IN VARCHAR2) by passing our sql query that’s it.

2) Now I am going to explain the code how it works. We all know every web page has header, body and footer content. In the same way every excel file has header, body, and footer.

3) First we will define and declare a directory variable by specifying file directory path where you want to save your files.

4) Grant the read and write access to your user to the SPLessons_Dir.

5) In the bellow code first it will create an excel file and open the file in write mode into a buffer.

6) Then the code will built our query result into the excel file format structure like table rows and columns and push that table content into the created excel file and save the file. Close the buffer.

CREATE OR REPLACE DIRECTORY SPLessons_DIR AS 'c:\myfiles' /* directory on the Oracle database server */ / GRANT READ, WRITE ON DIRECTORY SPLessons_DIR TO myuser / As myuser: DECLARE v_fh UTL_FILE.FILE_TYPE; v_dir VARCHAR2(30) := 'TEST_DIR'; v_file VARCHAR2(30) := 'myfile.xls'; PROCEDURE run_query(p_sql IN VARCHAR2) IS v_v_val VARCHAR2(4000); v_n_val NUMBER; v_d_val DATE; v_ret NUMBER; c NUMBER; d NUMBER; col_cnt INTEGER; f BOOLEAN; rec_tab DBMS_SQL.DESC_TAB; col_num NUMBER; BEGIN c := DBMS_SQL.OPEN_CURSOR; -- parse the SQL statement DBMS_SQL.PARSE(c, p_sql, DBMS_SQL.NATIVE); -- start execution of the SQL statement d := DBMS_SQL.EXECUTE(c); -- get a description of the returned columns DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab); -- bind variables to columns FOR j in 1..col_cnt LOOP CASE rec_tab(j).col_type WHEN 1 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,4000); WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_n_val); WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_d_val); ELSE DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,4000); END CASE; END LOOP; -- Output the column headers UTL_FILE.PUT_LINE(v_fh,'<ss:Row>'); FOR j in 1..col_cnt LOOP UTL_FILE.PUT_LINE(v_fh,'<ss:Cell>'); UTL_FILE.PUT_LINE(v_fh,'<ss:Data ss:Type="String">'||rec_tab(j).col_name||'</ss:Data>'); UTL_FILE.PUT_LINE(v_fh,'</ss:Cell>'); END LOOP; UTL_FILE.PUT_LINE(v_fh,'</ss:Row>'); -- Output the data LOOP v_ret := DBMS_SQL.FETCH_ROWS(c); EXIT WHEN v_ret = 0; UTL_FILE.PUT_LINE(v_fh,'<ss:Row>'); FOR j in 1..col_cnt LOOP CASE rec_tab(j).col_type WHEN 1 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_v_val); UTL_FILE.PUT_LINE(v_fh,'<ss:Cell>'); UTL_FILE.PUT_LINE(v_fh,'<ss:Data ss:Type="String">'||v_v_val||'</ss:Data>'); UTL_FILE.PUT_LINE(v_fh,'</ss:Cell>'); WHEN 2 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_n_val); UTL_FILE.PUT_LINE(v_fh,'<ss:Cell>'); UTL_FILE.PUT_LINE(v_fh,'<ss:Data ss:Type="Number">'||to_char(v_n_val)||'</ss:Data>'); UTL_FILE.PUT_LINE(v_fh,'</ss:Cell>'); WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_d_val); UTL_FILE.PUT_LINE(v_fh,'<ss:Cell ss:StyleID="OracleDate">'); UTL_FILE.PUT_LINE(v_fh,'<ss:Data ss:Type="DateTime">'||to_char(v_d_val,'YYYY-MM-DD"T"HH24:MI:SS')||'</ss:Data>'); UTL_FILE.PUT_LINE(v_fh,'</ss:Cell>'); ELSE DBMS_SQL.COLUMN_VALUE(c,j,v_v_val); UTL_FILE.PUT_LINE(v_fh,'<ss:Cell>'); UTL_FILE.PUT_LINE(v_fh,'<ss:Data ss:Type="String">'||v_v_val||'</ss:Data>'); UTL_FILE.PUT_LINE(v_fh,'</ss:Cell>'); END CASE; END LOOP; UTL_FILE.PUT_LINE(v_fh,'</ss:Row>'); END LOOP; DBMS_SQL.CLOSE_CURSOR(c); END; -- PROCEDURE start_workbook IS BEGIN UTL_FILE.PUT_LINE(v_fh,'<?xml version="1.0"?>'); UTL_FILE.PUT_LINE(v_fh,'<ss:Workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">'); END; PROCEDURE end_workbook IS BEGIN UTL_FILE.PUT_LINE(v_fh,'</ss:Workbook>'); END; -- PROCEDURE start_worksheet(p_sheetname IN VARCHAR2) IS BEGIN UTL_FILE.PUT_LINE(v_fh,'<ss:Worksheet ss:Name="'||p_sheetname||'">'); UTL_FILE.PUT_LINE(v_fh,'<ss:Table>'); END; PROCEDURE end_worksheet IS BEGIN UTL_FILE.PUT_LINE(v_fh,'</ss:Table>'); UTL_FILE.PUT_LINE(v_fh,'</ss:Worksheet>'); END; -- PROCEDURE set_date_style IS BEGIN UTL_FILE.PUT_LINE(v_fh,'<ss:Styles>'); UTL_FILE.PUT_LINE(v_fh,'<ss:Style ss:ID="OracleDate">'); UTL_FILE.PUT_LINE(v_fh,'<ss:NumberFormat ss:Format="dd/mm/yyyy\ hh:mm:ss"/>'); UTL_FILE.PUT_LINE(v_fh,'</ss:Style>'); UTL_FILE.PUT_LINE(v_fh,'</ss:Styles>'); END; BEGIN v_fh := UTL_FILE.FOPEN(upper(v_dir),v_file,'w',32767); start_workbook; set_date_style; start_worksheet('EMP'); run_query('select * from emp'); end_worksheet; UTL_FILE.FCLOSE(v_fh); END;