Salve,
come da titolo vorrei creare un file XLSX partendo da una tabella del mio schema e salvarlo in una directory.
Ovviamente il file deve essere la copia esatta della tabella.
Ho due problemi, il file viene creato ma ha solo l'intestazione delle colonne, ma sono tutte nella stessa riga separate da || se non ricordo male.
Inoltre se provo ad aprire il file mi dice che l'estensione non è supportata anche se il file viene creato con nome.xlsx.
Qualcuno saprebbe darmi una mano?
Qui sotto ho postato il codice da me scritto, che è un accozzaglia di cose che ho trovato su internet e di prove che ho fatto leggendo e mettendo in atto quello che avevo letto.
Grazie a chi vorrà darmi una mano.
create or replace PROCEDURE create_excel_filex1(
p_table_name VARCHAR2,
p_file_name VARCHAR2,
p_file_dir VARCHAR2
) IS
-- Definizione variabili
v_columns VARCHAR2(4000);
v_sql VARCHAR2(4000);
v_cursor INTEGER;
v_col_cnt INTEGER;
v_row_cnt INTEGER := 1;
v_file UTL_FILE.FILE_TYPE;
v_desc_tab DBMS_SQL.DESC_TAB;
v_desc DBMS_SQL.DESC_TAB;
p_file_path VARCHAR2(4000);
v_file_path VARCHAR2(4000);
v_row_count INTEGER;
v_col_value VARCHAR2(4000);
v_data varchar2(32767);
BEGIN
-- Costruisce la lista di colonne
DBMS_OUTPUT.PUT_LINE('Costruisce la lista di colonne Inizio ');
SELECT LISTAGG(column_name, ',') WITHIN GROUP (ORDER BY column_id)
INTO v_columns
FROM all_tab_columns
WHERE table_name = UPPER(p_table_name);
DBMS_OUTPUT.PUT_LINE('Costruisce la lista di colonne Fine ');
-- Costruisce la query di selezione dei dati
DBMS_OUTPUT.PUT_LINE(' Costruisce la query di selezione dei dati Inizio ');
v_sql := 'SELECT ' || v_columns || ' FROM ' || p_table_name;
DBMS_OUTPUT.PUT_LINE(' Costruisce la query di selezione dei dati Fine ');
-- Apre il cursore e ottiene il numero di colonne
DBMS_OUTPUT.PUT_LINE(' Apre il cursore e ottiene il numero di colonne Inizio ');
v_cursor := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(v_cursor, v_sql, DBMS_SQL.NATIVE);
v_col_cnt := DBMS_SQL.EXECUTE(v_cursor);
DBMS_OUTPUT.PUT_LINE(' Apre il cursore e ottiene il numero di colonne Fine ');
DBMS_OUTPUT.PUT_LINE(' v_col_cnt: '|| v_col_cnt);
-- Crea il file Excel
DBMS_OUTPUT.PUT_LINE(' Crea il file Excel Inizio ');
p_file_path := p_file_name||'.xlsx';
v_file := UTL_FILE.FOPEN(p_file_dir, p_file_path, 'w');
DBMS_OUTPUT.PUT_LINE(' Crea il file Excel Fine');
-- Scrive l'intestazione
DBMS_OUTPUT.PUT_LINE(' Scrive intestazione Inizio ');
DBMS_SQL.DESCRIBE_COLUMNS(v_cursor, v_col_cnt, v_desc_tab);
FOR i IN 1..v_col_cnt LOOP
DBMS_OUTPUT.PUT_LINE(' Scrive intestazione Sono nel Loop ');
UTL_FILE.PUT(v_file, '"' || v_desc_tab(i).col_name || '"' || CASE WHEN i = v_col_cnt THEN CHR(10) ELSE ',' END);
DBMS_OUTPUT.PUT_LINE(' Scrive intestazione Sono nel Loop 1');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' Scrive intestazione Fine ');
/* -- Scrive i dati
LOOP
v_row_count := DBMS_SQL.FETCH_ROWS(v_cursor);
EXIT WHEN v_row_count = 0;
FOR i IN 1..v_col_cnt LOOP
DBMS_SQL.COLUMN_VALUE(v_cursor, i, v_col_value);
UTL_FILE.PUT(v_file, '"' || COALESCE(v_col_value, '') || '"' || CASE WHEN i = v_col_cnt THEN CHR(10) ELSE ',' END);
END LOOP;
v_row_cnt := v_row_cnt + v_row_count;
END LOOP;*/
DBMS_OUTPUT.PUT_LINE(' Scrive i dati Inizio ');
while dbms_sql.fetch_rows(v_cursor) > 0
loop
DBMS_OUTPUT.PUT_LINE(' Scrive i dati Inizio Loop');
for i in 1..v_col_cnt
loop
DBMS_OUTPUT.PUT_LINE(' Scrive i dati Inizio Loop 2'|| v_col_cnt|| 'i'|| i);
dbms_sql.column_value(v_cursor, i, v_col_value);
DBMS_OUTPUT.PUT_LINE('column_value');
v_data := ltrim(v_data || replace(f_clean_special_char(v_col_value), ';', ' '));
DBMS_OUTPUT.PUT_LINE('v_data');
end loop;
DBMS_OUTPUT.PUT_LINE(' Scrive i dati fine Loop 2');
--
utl_file.put_line(v_file, v_data);
v_data := '';
end loop;
DBMS_OUTPUT.PUT_LINE(' Scrive i dati fine Loop');
-- Chiude il file e il cursore
UTL_FILE.FCLOSE(v_file);
DBMS_OUTPUT.PUT_LINE('File Chiuso');
DBMS_SQL.CLOSE_CURSOR(v_cursor);
DBMS_OUTPUT.PUT_LINE('Cursore Chiuso');
-- Stampa il messaggio di completamento
DBMS_OUTPUT.PUT_LINE('File ' || p_file_name || ' creato in ' || p_file_dir);
-- Stampa un messaggio di successo
EXCEPTION
-- In caso di errore, stampa il messaggio di errore e chiudi il file e il cursore
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Errore durante la creazione del file ' || p_file_name || ': ' || SQLERRM);
IF UTL_FILE.IS_OPEN(v_file) THEN
UTL_FILE.FCLOSE(v_file);
END IF;
IF DBMS_SQL.IS_OPEN(v_cursor) THEN
DBMS_SQL.CLOSE_CURSOR(v_cursor);
END IF;