設為首頁收藏本站

艾歐踢論壇

 找回密碼
 立即註冊

QQ登錄

只需一步,快速開始

搜索
熱搜: 活動 交友 discuz
查看: 2285|回復: 0
打印 上一主題 下一主題

Create an Excel File (.xlsx) using PL/SQL

[複製鏈接]
跳轉到指定樓層
樓主
發表於 2019-10-23 09:35:44 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
a package called as_xlsx by Anton Scheffer, Create an Excel-file with PL/SQL  modified it a bit to put in Worksheet Names and to allow SYS_REFCURSOR as a Parameter instead of a VARCHAR2  (Return the SQL Statement of an Explicit Cursor).
added this in the Package Specification for Procedure Overloading:
  1. procedure query2sheet
  2. ( p_cur             IN OUT      SYS_REFCURSOR
  3. , p_column_headers  boolean     := true
  4. , p_directory       varchar2    := null
  5. , p_filename        varchar2    := null
  6. , p_sheet           pls_integer := null
  7. , p_sheetname       varchar2    := null
複製代碼
The Package Body for Procedure Overloading
  1. <font face="inherit"></font><font color="#b09600"></font>procedure query2sheet
  2. ( p_cur IN OUT SYS_REFCURSOR
  3. , p_column_headers boolean := true
  4. , p_directory varchar2 := null
  5. , p_filename  varchar2 := null
  6. , p_sheet     pls_integer := null
  7. , p_sheetname varchar2 := null
  8. )
  9. is
  10.     t_sheet     pls_integer;
  11.     t_c         integer;
  12.     t_col_cnt   integer;
  13.     t_desc_tab2 dbms_sql.desc_tab2;
  14.     t_desc_tab  dbms_sql.desc_tab;
  15.     d_tab       dbms_sql.date_table;
  16.     n_tab       dbms_sql.number_table;
  17.     v_tab       dbms_sql.varchar2_table;
  18.     t_bulk_size pls_integer := 200;
  19.     t_r         integer;
  20.     t_cur_row   pls_integer;
  21.     t_d         number;
  22. begin
  23.     -- Changed
  24.     if p_sheetname is not null then
  25.         new_sheet(p_sheetname);      
  26.     else
  27.         new_sheet;
  28.     end if;
  29.     -- End of Change
  30.     --t_c := dbms_sql.open_cursor;                       
  31.     --dbms_sql.parse( t_c, p_sql, dbms_sql.native );

  32.     t_d := DBMS_SQL.TO_CURSOR_NUMBER(p_cur);

  33.     --dbms_sql.describe_columns2( t_c, t_col_cnt, t_desc_tab );
  34.     dbms_sql.describe_columns( t_d, t_col_cnt, t_desc_tab );

  35.     for c in 1 .. t_col_cnt
  36.     loop
  37.         if p_column_headers
  38.         then
  39.         cell( c, 1, t_desc_tab( c ).col_name, p_sheet => t_sheet );
  40.         end if;
  41.         --dbms_output.put_line( t_desc_tab( c ).col_name || ' ' || t_desc_tab( c ).col_type );
  42.         case
  43.         when t_desc_tab( c ).col_type in ( 2, 100, 101 )
  44.         then
  45.             --dbms_sql.define_array( t_c, c, n_tab, t_bulk_size, 1 );
  46.             dbms_sql.define_array( t_d, c, n_tab, t_bulk_size, 1 );
  47.         when t_desc_tab( c ).col_type in ( 12, 178, 179, 180, 181 , 231 )
  48.         then
  49.             --dbms_sql.define_array( t_c, c, d_tab, t_bulk_size, 1 );
  50.             dbms_sql.define_array( t_d, c, d_tab, t_bulk_size, 1 );
  51.         when t_desc_tab( c ).col_type in ( 1, 8, 9, 96, 112 )
  52.         then
  53.             --dbms_sql.define_array( t_c, c, v_tab, t_bulk_size, 1 );
  54.             dbms_sql.define_array( t_d, c, v_tab, t_bulk_size, 1 );
  55.         else
  56.             null;
  57.         end case;
  58.     end loop;
  59.     --
  60.     t_cur_row := case when p_column_headers then 2 else 1 end;
  61.     t_sheet := nvl( p_sheet, workbook.sheets.count() );
  62.     --
  63.     --t_r := dbms_sql.execute( t_c );
  64.     loop
  65.         --t_r := dbms_sql.fetch_rows( t_c );
  66.         t_r := dbms_sql.fetch_rows( t_d );
  67.         if t_r > 0
  68.         then
  69.         for c in 1 .. t_col_cnt
  70.         loop
  71.             case
  72.             when t_desc_tab( c ).col_type in ( 2, 100, 101 )
  73.             then
  74.                 --dbms_sql.column_value( t_c, c, n_tab );
  75.                 dbms_sql.column_value( t_d, c, n_tab );
  76.                 for i in 0 .. t_r - 1
  77.                 loop
  78.                 if n_tab( i + n_tab.first() ) is not null
  79.                 then
  80.                     cell( c, t_cur_row + i, n_tab( i + n_tab.first() ), p_sheet => t_sheet );
  81.                 end if;
  82.                 end loop;
  83.                 n_tab.delete;
  84.             when t_desc_tab( c ).col_type in ( 12, 178, 179, 180, 181 , 231 )
  85.             then
  86.                 --dbms_sql.column_value( t_c, c, d_tab );
  87.                 dbms_sql.column_value( t_d, c, d_tab );
  88.                 for i in 0 .. t_r - 1
  89.                 loop
  90.                 if d_tab( i + d_tab.first() ) is not null
  91.                 then
  92.                     cell( c, t_cur_row + i, d_tab( i + d_tab.first() ), p_sheet => t_sheet );
  93.                 end if;
  94.                 end loop;
  95.                 d_tab.delete;
  96.             when t_desc_tab( c ).col_type in ( 1, 8, 9, 96, 112 )
  97.             then
  98.                 --dbms_sql.column_value( t_c, c, v_tab );
  99.                 dbms_sql.column_value( t_d, c, v_tab );
  100.                 for i in 0 .. t_r - 1
  101.                 loop
  102.                 if v_tab( i + v_tab.first() ) is not null
  103.                 then
  104.                     cell( c, t_cur_row + i, v_tab( i + v_tab.first() ), p_sheet => t_sheet );
  105.                 end if;
  106.                 end loop;
  107.                 v_tab.delete;
  108.             else
  109.                 null;
  110.             end case;
  111.         end loop;
  112.         end if;
  113.         exit when t_r != t_bulk_size;
  114.         t_cur_row := t_cur_row + t_r;
  115.     end loop;
  116.     --dbms_sql.close_cursor( t_c );
  117.     dbms_sql.close_cursor( t_d );
  118.     if ( p_directory is not null and  p_filename is not null )
  119.     then
  120.         save( p_directory, p_filename );
  121.     end if;
  122. exception
  123. when others
  124. then
  125.     --if dbms_sql.is_open( t_c )
  126.     if dbms_sql.is_open( t_d )
  127.     then
  128.     --dbms_sql.close_cursor( t_c );
  129.     dbms_sql.close_cursor( t_d );
  130.     end if;
  131. end query2sheet;
複製代碼
This is a Sample Block in my Concurrent Request that Creates the File:
  1. Procedure EMP_ROSTER_REPORT (p_empno        per_all_people_f.employee_number%type                              
  2.                            , p_bg_id        per_business_groups.business_group_id%type
  3.                            , p_email_add    per_all_people_f.email_address%type)
  4. is

  5.     l_fh            UTL_FILE.FILE_TYPE;
  6.     l_directory     VARCHAR2(30) := 'EXT_TAB_DATA';
  7.     l_filename      VARCHAR2(100);
  8.     emp_cur         SYS_REFCURSOR;
  9.     l_message       varchar2(100);
  10.     g_stage         varchar2(100);
  11.     g_zipped_blob   blob;

  12.     cursor  p_payroll_cur is
  13.     select  payroll_id
  14.         ,   payroll_name
  15.         ,   business_group_id
  16.     from    pay_all_payrolls_f
  17.     where   business_group_id = p_bg_id;

  18. BEGIN

  19.     -----------------------------------
  20.     g_stage := 'setting the filename';
  21.     -----------------------------------

  22.     l_filename := 'EMPLOYEE_ROSTER_REPORT_'||TO_CHAR(SYSDATE, 'DD-MON-YYYY-HHMISS');

  23.     ------------------------------------------
  24.     g_stage := 'Assigning Emp SysRefCursor';
  25.     ------------------------------------------

  26.     for i in p_payroll_cur loop

  27.         OPEN emp_cur FOR
  28.         SELECT  'extra long query here with parameters'
  29.         from    table_a
  30.         where   payroll_id = i.payroll_id;

  31.         ----------------------------------------------------------
  32.         g_stage := 'open Employee Cursor and write into the File';
  33.         ----------------------------------------------------------

  34.         as_xlsx.query2sheet( p_cur          => emp_cur            -- Uses Sys_RefCursor Instead of Dynamic SQL (Varchar2)
  35.                            , p_sheetname    => i.payroll_name);   -- This is where we assign the Sheet Names         
  36.         as_xlsx.freeze_pane( 1,1 );                               -- Freeze the topmost and rightmost pane in the Excel Sheet

  37.     end loop;

  38.     ------------------------------
  39.     g_stage := 'Create the File';
  40.     ------------------------------

  41.     as_xlsx.save( l_directory , l_filename||'.xlsx');

  42. END EMP_ROSTER_REPORT;
複製代碼

There is no support for xls or xlsx files in Oracle database as such.
What you can do is create CSV (Comma Separated) file and then, compress it into a zip file using a custom java stored procedure which uses java.util.zip, or a PL/SQL procedure that uses UTL_COMPRESS.




分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 轉播轉播 分享分享 分享淘帖
回復

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 立即註冊

本版積分規則

小黑屋|Archiver|手機版|艾歐踢創新工坊    

GMT+8, 2024-5-16 01:50 , Processed in 0.252846 second(s), 19 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表