EBS開發附件上傳和下載功能(轉)


原文地址:

EBS開發附件上傳和下載功能

上傳

Oracle ERP二次開發中使用的方式有兩種,一是通過標准功能,在系統管理員中定義即可,不用寫代碼,就可以使幾乎任何Form具有附件功能,具體參考系統管理員文檔;二是通過PL/SQL Gateway,需要我們便寫代碼完成。該方式其實和上述方式一的后台實現是一樣的

程序說明

1、Package功能,測試通過PL/SQLGateway(MOD PL/SQL)完成文件上傳下載  
  2、本Package直接使用EBS的DAD,所以對應的Document表為APPS.fnd_lobs_document
    在非EBS環境開發,需要自己定義DAD請參考9ias_plsql.pdf和9ias.pdf,步驟如下
    a、創建Document表,參照fnd_lobs_document和fnd_lobs_documentpart,表名自己起
    b、配置DAD,配置文件為$IAS_ORACLE_HOME/Apache/modplsql/cfg/wdbsvr.app
    c、參照fnd_gfm,改寫成自己的包,或者簡單點改寫本Package也行
  3、需要把我們寫的包在system administrator--> security --> Web PL/SQL里面注冊一下,
    不然通過IE打開會提示用戶名和密碼
  4、本測試把在“接口”fnd_lobs_document中的附件,按照EBS的做法保存到fnd_lobs,
    也可以改寫代碼保存到自己的表,一般沒必要,我們自己的表保存File_ID即可
  5、一個表中的BLOB等數據可以直接插入另一個表

下載

上傳的文件時存到了fnd_lobs表中以BLOB數據的形式存儲,現在要把BLOB數據以原文件的格式讀取出來,並且給最終用戶提供下載該文件的功能

方法如下:

DECLARE
  v_file_id NUMBER;
  url       VARCHAR2(500);
BEGIN
  --Get the file_id of the file which you want to download in fnd_lobs 
  v_file_id := xxxxxx;
  --Get The Download URL
  url := fnd_gfm.construct_download_url(fnd_web_config.gfm_agent,
                                        v_file_id,
                                        TRUE);
  fnd_utilities.open_url(url);
END;

以上的方法就可以輕松的實現下載存儲在fnd_lobs中的文件,只要告訴fnd_gfm.construct_download_url在fnd_lobs表中文件的file_id,就可以輕松取得URL,使用fnd_utilities.open_url就可以下載該文件;不過現在還有一個問題就是要在工作流發送的消息找到一個東西(比如說一個按鈕、超鏈接)來執行下載文件的方法可以在document類型的ATTRIBUTE里設置一個超鏈接,然后讓這個超鏈接的地址指向我已經取得的下載文件的URL

CREATE OR REPLACE PACKAGE cux_oracle_up_down_pkg AUTHID CURRENT_USER IS
  /********************************************
  1、Package功能,測試通過PL/SQL Gateway(MOD PL/SQL)完成文件上傳下載
  2、本Package直接使用EBS的DAD,所以對應的Document表為APPS.fnd_lobs_document
    在非EBS環境開發,需要自己定義DAD請參考9ias_plsql.pdf和9ias.pdf,步驟如下
    1、創建Document表,參照fnd_lobs_document和fnd_lobs_documentpart,表名自己起
    2、配置DAD,配置文件為$IAS_ORACLE_HOME/Apache/modplsql/cfg/wdbsvr.app
    3、參照fnd_gfm,改寫成自己的包,或者簡單點改寫本Package也行
  3、需要把我們寫的包在system administrator --> security --> Web PL/SQL里面注冊一下,
    不然通過IE打開會提示用戶名和密碼
  4、本測試把在“接口”fnd_lobs_document中的附件,按照EBS的做法保存到fnd_lobs,
    也可以改寫代碼保存到自己的表,一般沒必要,我們自己的表保存File_ID即可
  5、一個表中的BLOB等數據可以直接插入另一個表
  
  ********************************************/
  /***************上傳文件下載過程*************
  1、初始化access id
  select fnd_gfm.authorize(-1) from dual;
  
  2、准備url,下面是例子
  SELECT fnd_web_config.trail_slash(fnd_profile.VALUE('APPS_WEB_AGENT')) ||
       'oracle_up_down.upload_form?p_access_id=上面1的查詢結果'
  FROM dual;
  
  3、用瀏覽器打開url即可。如果是通過Form打開url上傳,那么把上面代碼放入form的相應trigger
  
  4、查看File_ID
  SELECT fnd_web_config.trail_slash(fnd_profile.VALUE('APPS_WEB_AGENT')) ||
       'oracle_up_down.upload_form?p_access_id=上面1的查詢結果'
  FROM dual;
  
  4、把文件下載下來驗證
  SELECT fnd_web_config.trail_slash(fnd_profile.VALUE('APPS_WEB_AGENT')) ||
       'oracle_up_down.download_file?p_file_id=上面4的查詢結果' || chr(38) ||
       'p_access_id=上面1的查詢結果'
  FROM dual;
  
  5、可以直接在PL/SQL Developer 6以上中Select出來點擊File_Data察看
  
  Test腳本
  http://hw321.huawei.com:8003/pls/scp/fnd_web.SHOWENV;
  select fnd_gfm.authorize(-1) from dual;
  select * from applsys.fnd_lob_access t where t.access_id = 354896931892;
  http://hw321.huawei.com:8003/pls/SCP/oracle_up_down.upload_form?p_access_id=354896931892;
  select * from applsys.fnd_lob_access t where t.access_id = 354896931892;
  select * from applsys.fnd_lobs_document t;
  http://hw321.huawei.com:8003/pls/SCP/oracle_up_down.download_file?p_file_id=3548970&p_access_id=354896931892;
  Select * from fnd_lobs flb where flb.file_id = 3548970;
  ****************上傳文件下載過程*****************/

  g_agent        CONSTANT VARCHAR2(100) := fnd_web_config.trail_slash(fnd_profile.value('APPS_WEB_AGENT'));
  g_package_name CONSTANT VARCHAR2(100) := 'oracle_up_down';
  g_upload_url   CONSTANT VARCHAR2(100) := g_package_name || '.upload_file';
  g_download_url CONSTANT VARCHAR2(100) := g_package_name ||
                                           '.download_file';
  g_cancel_url   CONSTANT VARCHAR2(100) := g_package_name || '.cancel_file';

  --完成上傳:把在網關中的數據抓到自己的表
  PROCEDURE upload_file(p_file_name IN VARCHAR2, p_access_id IN NUMBER);
  --顯示HTML取消頁面
  PROCEDURE upload_cancel;
  --顯示HTML上傳頁面
  PROCEDURE upload_form(p_access_id IN NUMBER DEFAULT NULL);
  --下載文件
  PROCEDURE download_file(p_file_id   IN NUMBER,
                          p_access_id IN NUMBER,
                          p_purge     IN VARCHAR2 DEFAULT NULL);

  PROCEDURE download_file_html(p_file_id   IN NUMBER,
                               p_access_id IN NUMBER,
                               p_purge     IN VARCHAR2 DEFAULT NULL);

END;
CREATE OR REPLACE PACKAGE BODY cux_oracle_up_down_pkg IS

  --add '/' to a string
  FUNCTION trail_slash(p_val IN VARCHAR2) RETURN VARCHAR2 IS
    l_copy_val VARCHAR2(2000);
  BEGIN
    l_copy_val := p_val;
    WHILE (substr(l_copy_val, -1, 1) = '/') LOOP
      l_copy_val := substr(l_copy_val, 1, length(l_copy_val) - 1);
    END LOOP;
    RETURN l_copy_val || '/';
  END;

  PROCEDURE err_msg(NAME VARCHAR2) IS
  BEGIN
    fnd_message.set_name('FND', 'SQL_PLSQL_ERROR');
    fnd_message.set_token('ROUTINE', 'FND_GFM.' || NAME);
    fnd_message.set_token('ERRNO', SQLCODE);
    fnd_message.set_token('REASON', SQLERRM);
  END err_msg;

  /*
  從fnd_gfm拷貝過來,原來的代碼是刪除整個fnd_lobs_document,不知道為何,現在改為僅刪除上傳的文件
  */

  FUNCTION confirm_upload(access_id       NUMBER,
                          file_name       VARCHAR2,
                          program_name    VARCHAR2 DEFAULT NULL,
                          program_tag     VARCHAR2 DEFAULT NULL,
                          expiration_date DATE DEFAULT NULL,
                          LANGUAGE        VARCHAR2 DEFAULT userenv('LANG'),
                          wakeup          BOOLEAN DEFAULT FALSE)
    RETURN NUMBER IS
    fid        NUMBER := -1;
    fn         VARCHAR2(256);
    mt         VARCHAR2(240);
    bloblength NUMBER; -- bug 3045375, added variable to set length of blob.
  BEGIN
    IF (fnd_gfm.authenticate(confirm_upload.access_id)) THEN
      SELECT fnd_lobs_s.nextval INTO fid FROM dual;
    
      fn := substr(confirm_upload.file_name,
                   instr(confirm_upload.file_name, '/') + 1);
    
      -- bug 3045375, added select to get length of BLOB.
      SELECT dbms_lob.getlength(blob_content), mime_type
        INTO bloblength, mt
        FROM fnd_lobs_document
       WHERE NAME = confirm_upload.file_name
         AND rownum = 1;
    
      -- bug 3045375, added if to check length of blob.
      IF bloblength > 0 THEN
        INSERT INTO fnd_lobs
          (file_id,
           file_name,
           file_content_type,
           file_data,
           upload_date,
           expiration_date,
           program_name,
           program_tag,
           LANGUAGE,
           file_format)
          (SELECT confirm_upload.fid,
                  fn,
                  ld.mime_type,
                  ld.blob_content,
                  SYSDATE,
                  confirm_upload.expiration_date,
                  confirm_upload.program_name,
                  confirm_upload.program_tag,
                  confirm_upload.language,
                  fnd_gfm.set_file_format(mt)
             FROM fnd_lobs_document ld
            WHERE ld.name = confirm_upload.file_name
              AND rownum = 1);
      
        IF (SQL%ROWCOUNT <> 1) THEN
          RAISE no_data_found;
        END IF;
      
        UPDATE fnd_lob_access
           SET file_id = fid
         WHERE access_id = confirm_upload.access_id;
      
        IF wakeup THEN
          dbms_alert.signal('FND_GFM_ALERT' || to_char(access_id),
                            to_char(fid));
        END IF;
        -- bug 3045375, added else to return fid = -2.
      ELSE
        fid := -2;
      END IF;
      DELETE FROM fnd_lobs_document ld
       WHERE ld.name = confirm_upload.file_name;
      --delete from fnd_lobs_documentpart;
    END IF;
    RETURN fid;
  EXCEPTION
    WHEN OTHERS THEN
      DELETE FROM fnd_lobs_document ld
       WHERE ld.name = confirm_upload.file_name;
      --delete from fnd_lobs_documentpart;
    
      err_msg('confirm_upload');
      RAISE;
  END;

  PROCEDURE upload_file(p_file_name IN VARCHAR2, p_access_id IN NUMBER) IS
    l_file_id NUMBER;
  BEGIN
  
    l_file_id := confirm_upload(access_id    => p_access_id,
                                file_name    => p_file_name,
                                program_name => g_package_name);
  
    IF l_file_id NOT IN (-1, -2) THEN
      -- File upload completed
      htp.htmlopen;
      htp.headopen;
      htp.title('文件上傳');
      htp.headclose;
      htp.bodyopen;
      htp.img2('/images/wwcban.jpg', calign => 'Center', calt => 'Logo');
      htp.br;
      htp.br;
      htp.p('<h4>' || '文件上傳' || '</h4>');
      htp.hr;
      htp.p(htf.bold('文件上傳完成。Select * from fnd_lobs flb where flb.file_id = ' ||
                     l_file_id));
      htp.br;
    
      htp.p('<h4>' || '請關閉瀏覽器!' || '</h4>');
      htp.br;
      htp.bodyclose;
      htp.htmlclose;
    
    ELSE
      -- File upload failed.
      htp.htmlopen;
      htp.headopen;
      htp.title('文件上傳');
      htp.headclose;
      htp.bodyopen;
      htp.img2('/images/wwcban.jpg', calign => 'Left', calt => 'Logo');
      htp.br;
    
      htp.hr;
      htp.p(htf.bold('文件上傳失敗!'));
      htp.br;
      htp.bodyclose;
      htp.htmlclose;
    END IF;
  
  END;

  PROCEDURE upload_cancel AS
  
  BEGIN
  
    -- Show a message page
    htp.htmlopen;
    htp.headopen;
    htp.title('取消文件上傳');
    htp.headclose;
    htp.bodyopen;
    htp.img2('/images/wwcban.jpg', calign => 'Center', calt => 'Logo');
    htp.br;
    htp.br;
    htp.p('<h4>' || '文件上傳' || '</h4>');
    htp.hr;
    htp.p(htf.bold('取消文件上傳'));
    htp.br;
    htp.p('<h4>' || '您已經選擇取消文件上傳。' || '</h4>');
    htp.p('<h4>' || '請關閉瀏覽器!' || '</h4>');
    htp.br;
    htp.br;
    htp.br;
    htp.bodyclose;
    htp.htmlclose;
  
  END;

  PROCEDURE upload_form(p_access_id IN NUMBER DEFAULT NULL) IS
    l_upload_action VARCHAR2(2000);
  BEGIN
  
    -- Set the upload action
    l_upload_action := fnd_gfm.construct_upload_url(g_agent,
                                                    g_upload_url,
                                                    p_access_id);
    -- Set page title and toolbar.
    htp.htmlopen;
    htp.headopen;
    htp.p('<SCRIPT LANGUAGE="JavaScript">');
    htp.p(' function processclick (cancel_url) {
                 if (confirm(' || '"' || '取消文件上傳' || '"' || '))
                 {
                        parent.location=cancel_url
                 }
              }');
    htp.print('</SCRIPT>');
    htp.title('文件上傳');
    htp.headclose;
    htp.bodyopen;
    htp.img2('/images/wwcban.jpg', calign => 'Center', calt => 'Logo');
    htp.br;
    htp.br;
    htp.p('<h4>' || '文件上傳' || '</h4>');
    htp.hr;
    htp.br;
    htp.print('</LEFT>');
  
    htp.formopen(curl     => l_upload_action,
                 cmethod  => 'POST',
                 cenctype => 'multipart/form-data');
    htp.tableopen(cattributes => ' border=0 cellpadding=2 cellspacing=0');
    htp.tablerowopen;
    htp.tablerowclose;
  
    htp.tablerowopen(cvalign => 'TOP');
    htp.p('<TD>');
    htp.p('</TD>');
    htp.p('<label>文件</label>');
    htp.tabledata('<INPUT TYPE="File" NAME="p_file_name" SIZE="60">',
                  calign => 'left');
    htp.tablerowclose;
    htp.tableclose;
  
    -- Send access is as a hidden value
    htp.formhidden(cname => 'p_access_id', cvalue => to_char(p_access_id));
  
    htp.br;
    htp.tableopen(cattributes => ' border=0 cellpadding=2 cellspacing=0');
    htp.tablerowopen(cvalign => 'TOP');
    htp.tabledata('<INPUT TYPE="Submit" VALUE="' || '確定' || '" SIZE="50">',
                  calign => 'left');
    htp.tabledata('<INPUT TYPE="Button" NAME="cancel" VALUE="' || '取消' || '"' ||
                  ' onClick="processclick(''' || g_cancel_url ||
                  ''') " SIZE="50">',
                  calign => 'left');
    htp.tablerowclose;
    htp.tableclose;
    htp.formclose;
  
    htp.bodyclose;
    htp.htmlclose;
  END;

  PROCEDURE download_file(p_file_id   IN NUMBER,
                          p_access_id IN NUMBER,
                          p_purge     IN VARCHAR2 DEFAULT NULL) IS
  BEGIN
    fnd_gfm.download(p_file_id, p_access_id, p_purge);
  END;

  PROCEDURE download_file_html(p_file_id   IN NUMBER,
                               p_access_id IN NUMBER,
                               p_purge     IN VARCHAR2 DEFAULT NULL) IS
  BEGIN
    htp.print('
    <html>
    <body>
      <img src=' || g_download_url || '?p_file_id=' ||
              p_file_id || chr(38) || 'p_access_id=' || p_access_id ||
              ' border=0>
    </body>
    </html>
    ');
  END;
END;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM