Oracle Reports 需提供 CSV/Excel 下載連結時,透過 Format Trigger 動態顯示超連結,配合自訂 Package 組裝檔案內容並寫入 Web 可存取目錄。
FUNCTION B_DOWNLOADFormatTrigger RETURN BOOLEAN IS
BEGIN
IF UPPER(:P_ACTION) != 'DOWNLOAD' THEN
RETURN FALSE; -- 非下載模式隱藏
ELSE
SRW.SET_HYPERLINK(EXP_FILE.GET_DOWNLOAD_URL);
RETURN TRUE;
END IF;
END;
CREATE OR REPLACE PACKAGE EXP_FILE IS
FUNCTION GET_DOWNLOAD_URL RETURN VARCHAR2;
FUNCTION CREATE_FILE(p_prefix VARCHAR2, p_ext VARCHAR2) RETURN BOOLEAN;
PROCEDURE WRITE_LINE(p_line VARCHAR2);
PROCEDURE CLOSE_FILE;
END;
/
CREATE OR REPLACE PACKAGE BODY EXP_FILE IS
g_file UTL_FILE.FILE_TYPE;
g_filename VARCHAR2(200);
g_url_base VARCHAR2(500) := 'https://reports-server/reports/output/'; -- Web 可存取 URL 前綴
FUNCTION GET_DOWNLOAD_URL RETURN VARCHAR2 IS
BEGIN
RETURN g_url_base || g_filename;
END;
FUNCTION CREATE_FILE(p_prefix VARCHAR2, p_ext VARCHAR2) RETURN BOOLEAN IS
BEGIN
g_filename := p_prefix || '_' || TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS') || '.' || p_ext;
g_file := UTL_FILE.FOPEN('REPORTS_OUTPUT_DIR', g_filename, 'W', 32767);
RETURN TRUE;
EXCEPTION
WHEN OTHERS THEN
RETURN FALSE;
END;
PROCEDURE WRITE_LINE(p_line VARCHAR2) IS
BEGIN
UTL_FILE.PUT_LINE(g_file, p_line);
END;
PROCEDURE CLOSE_FILE IS
BEGIN
UTL_FILE.FCLOSE(g_file);
END;
END;
/
```
3. Before Report Trigger
FUNCTION BeforeReport RETURN BOOLEAN IS
BEGIN
IF UPPER(:P_ACTION) = 'DOWNLOAD' THEN
EXP_FILE.CREATE_FILE('Emp_Report', 'csv');
-- 表頭
EXP_FILE.WRITE_LINE('部門,員工姓名,職稱,薪資,入職日期');
-- 此處可開啟游標迴圈寫入明細
-- FOR rec IN (SELECT ... FROM ...) LOOP
-- EXP_FILE.WRITE_LINE(rec.dept||','||rec.ename||','||rec.job||','||rec.sal||','||rec.hiredate);
-- END LOOP;
EXP_FILE.CLOSE_FILE;
END IF;
RETURN TRUE;
END;
4. 必備環境配置
- 建立 Directory 物件:
CREATE DIRECTORY REPORTS_OUTPUT_DIR AS '/u01/reports/output';
- Reports Server
rwservlet.properties 對應 webRoot 指向同一物理目錄。
- 前端呼叫:
https://host:port/reports/rwservlet?report=emp_report&action=DOWNLOAD&userid=...
現代化替代建議
Oracle APEX Interactive Report / ORDS REST + 前端 SheetJS 可完全取代,維護成本更低、使用者體驗更好。
掌握 Format Trigger + UTL_FILE + Directory 三部曲,舊版 Reports 也能優雅提供下載。