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数据以原文件的格式读取出来,并且给最终用户提供下载该文件的功能

方法如下

[sql]  view plain  copy
  1. <span style="font-size:18px;">declare  
  2. v_file_id NUMBER;  
  3. url VARCHAR2(500);  
  4. begin   
  5. --Get the file_id of the file which you want to download in fnd_lobs   
  6. v_file_id := xxxxxx;  
  7. --Get The Download URL  
  8. url := fnd_gfm.construct_download_url(fnd_web_config.gfm_agent,v_file_id,TRUE);  
  9. fnd_utilities.open_url(url);  
  10. end;  
  11. </span>  

以上的方法就可以轻松的实现下载存储在fnd_lobs中的文件,只要告诉fnd_gfm.construct_download_urlfnd_lobs表中文件的file_id,就可以轻松取得URL,使用fnd_utilities.open_url就可以下载该文件;不过现在还有一个问题就是要在工作流发送的消息找到一个东西(比如说一个按钮、超链接)来执行下载文件的方法可以在document类型的ATTRIBUTE里设置一个超链接,然后让这个超链接的地址指向我已经取得的下载文件的URL

[html]  view plain  copy
  1. <span style="font-size:18px;">CREATE OR REPLACE PACKAGE oracle_up_down AUTHID CURRENT_USER IS  
  2.   /********************************************  
  3.   1、Package功能,测试通过PL/SQL Gateway(MOD PL/SQL)完成文件上传下载    
  4.   2、本Package直接使用EBS的DAD,所以对应的Document表为APPS.fnd_lobs_document  
  5.     在非EBS环境开发,需要自己定义DAD请参考9ias_plsql.pdf和9ias.pdf,步骤如下  
  6.     1、创建Document表,参照fnd_lobs_document和fnd_lobs_documentpart,表名自己起  
  7.     2、配置DAD,配置文件为$IAS_ORACLE_HOME/Apache/modplsql/cfg/wdbsvr.app  
  8.     3、参照fnd_gfm,改写成自己的包,或者简单点改写本Package也行  
  9.   3、需要把我们写的包在system administrator --> security --> Web PL/SQL里面注册一下,  
  10.     不然通过IE打开会提示用户名和密码  
  11.   4、本测试把在“接口”fnd_lobs_document中的附件,按照EBS的做法保存到fnd_lobs,  
  12.     也可以改写代码保存到自己的表,一般没必要,我们自己的表保存File_ID即可  
  13.   5、一个表中的BLOB等数据可以直接插入另一个表  
  14.     
  15.   ********************************************/  
  16.   /***************上传文件下载过程*************  
  17.   1、初始化access id  
  18.   select fnd_gfm.authorize(-1) from dual;  
  19.     
  20.   2、准备url,下面是例子  
  21.   SELECT fnd_web_config.trail_slash(fnd_profile.VALUE('APPS_WEB_AGENT')) ||  
  22.        'oracle_up_down.upload_form?p_access_id=上面1的查询结果'  
  23.   FROM dual;  
  24.     
  25.   3、用浏览器打开url即可。如果是通过Form打开url上传,那么把上面代码放入form的相应trigger  
  26.     
  27.   4、查看File_ID  
  28.   SELECT fnd_web_config.trail_slash(fnd_profile.VALUE('APPS_WEB_AGENT')) ||  
  29.        'oracle_up_down.upload_form?p_access_id=上面1的查询结果'  
  30.   FROM dual;  
  31.     
  32.   4、把文件下载下来验证  
  33.   SELECT fnd_web_config.trail_slash(fnd_profile.VALUE('APPS_WEB_AGENT')) ||  
  34.        'oracle_up_down.download_file?p_file_id=上面4的查询结果' || chr(38) ||  
  35.        'p_access_id=上面1的查询结果'  
  36.   FROM dual;  
  37.     
  38.   5、可以直接在PL/SQL Developer 6以上中Select出来点击File_Data察看  
  39.     
  40.   Test脚本  
  41.   http://hw321.huawei.com:8003/pls/scp/fnd_web.SHOWENV;  
  42.   select fnd_gfm.authorize(-1) from dual;  
  43.   select * from applsys.fnd_lob_access t where t.access_id = 354896931892;  
  44.   http://hw321.huawei.com:8003/pls/SCP/oracle_up_down.upload_form?p_access_id=354896931892;  
  45.   select * from applsys.fnd_lob_access t where t.access_id = 354896931892;  
  46.   select * from applsys.fnd_lobs_document t;  
  47.   http://hw321.huawei.com:8003/pls/SCP/oracle_up_down.download_file?p_file_id=3548970&p_access_id=354896931892;  
  48.   Select * from fnd_lobs flb where flb.file_id = 3548970;  
  49.   ****************上传文件下载过程*****************/  
  50.   
  51.   g_agent        CONSTANT VARCHAR2(100) :fnd_web_config.trail_slash(fnd_profile.VALUE('APPS_WEB_AGENT'));  
  52.   g_package_name CONSTANT VARCHAR2(100) :'oracle_up_down';  
  53.   g_upload_url   CONSTANT VARCHAR2(100) :g_package_name || '.upload_file';  
  54.   g_download_url CONSTANT VARCHAR2(100) :g_package_name ||  
  55.                                            '.download_file';  
  56.   g_cancel_url   CONSTANT VARCHAR2(100) :g_package_name || '.cancel_file';  
  57.   
  58.   --完成上传:把在网关中的数据抓到自己的表  
  59.   PROCEDURE upload_file(p_file_name IN VARCHAR2, p_access_id IN NUMBER);  
  60.   --显示HTML取消页面  
  61.   PROCEDURE upload_cancel;  
  62.   --显示HTML上传页面  
  63.   PROCEDURE upload_form(p_access_id IN NUMBER DEFAULT NULL);  
  64.   --下载文件  
  65.   PROCEDURE download_file(p_file_id   IN NUMBER,  
  66.                           p_access_id IN NUMBER,  
  67.                           p_purge     IN VARCHAR2 DEFAULT NULL);  
  68.   
  69.   PROCEDURE download_file_html(p_file_id   IN NUMBER,  
  70.                                p_access_id IN NUMBER,  
  71.                                p_purge     IN VARCHAR2 DEFAULT NULL);  
  72.   
  73. END;  
  74. /  
  75. CREATE OR REPLACE PACKAGE BODY oracle_up_down IS  
  76.   
  77.   --add '/' to a string  
  78.   FUNCTION trail_slash(p_val IN VARCHAR2) RETURN VARCHAR2 IS  
  79.     l_copy_val VARCHAR2(2000);  
  80.   BEGIN  
  81.     l_copy_val :p_val;  
  82.     WHILE (substr(l_copy_val, -1, 1) = '/') LOOP  
  83.       l_copy_val :substr(l_copy_val, 1, length(l_copy_val) - 1);  
  84.     END LOOP;  
  85.     RETURN l_copy_val || '/';  
  86.   END;  
  87.   
  88.   PROCEDURE err_msg(NAME VARCHAR2) IS  
  89.   BEGIN  
  90.     fnd_message.set_name('FND', 'SQL_PLSQL_ERROR');  
  91.     fnd_message.set_token('ROUTINE', 'FND_GFM.' || NAME);  
  92.     fnd_message.set_token('ERRNO', SQLCODE);  
  93.     fnd_message.set_token('REASON', SQLERRM);  
  94.   END err_msg;  
  95.   
  96.   /*  
  97.   从fnd_gfm拷贝过来,原来的代码是删除整个fnd_lobs_document,不知道为何,现在改为仅删除上传的文件  
  98.   */  
  99.   
  100.   FUNCTION confirm_upload(access_id       NUMBER,  
  101.                           file_name       VARCHAR2,  
  102.                           program_name    VARCHAR2 DEFAULT NULL,  
  103.                           program_tag     VARCHAR2 DEFAULT NULL,  
  104.                           expiration_date DATE DEFAULT NULL,  
  105.                           LANGUAGE        VARCHAR2 DEFAULT userenv('LANG'),  
  106.                           wakeup          BOOLEAN DEFAULT FALSE)  
  107.     RETURN NUMBER IS  
  108.     fid        NUMBER := -1;  
  109.     fn         VARCHAR2(256);  
  110.     mt         VARCHAR2(240);  
  111.     bloblength NUMBER; -- bug 3045375, added variable to set length of blob.  
  112.   BEGIN  
  113.     IF (fnd_gfm.authenticate(confirm_upload.access_id)) THEN  
  114.       SELECT fnd_lobs_s.NEXTVAL INTO fid FROM dual;  
  115.       
  116.       fn :substr(confirm_upload.file_name,  
  117.                    instr(confirm_upload.file_name, '/') + 1);  
  118.       
  119.       -- bug 3045375, added select to get length of BLOB.  
  120.       SELECT dbms_lob.getlength(blob_content), mime_type  
  121.         INTO bloblength, mt  
  122.         FROM fnd_lobs_document  
  123.        WHERE NAME = confirm_upload.file_name  
  124.          AND rownum = 1;  
  125.       
  126.       -- bug 3045375, added if to check length of blob.  
  127.       IF bloblength > 0 THEN  
  128.         INSERT INTO fnd_lobs  
  129.           (file_id,  
  130.            file_name,  
  131.            file_content_type,  
  132.            file_data,  
  133.            upload_date,  
  134.            expiration_date,  
  135.            program_name,  
  136.            program_tag,  
  137.            LANGUAGE,  
  138.            file_format)  
  139.           (SELECT confirm_upload.fid,  
  140.                   fn,  
  141.                   ld.mime_type,  
  142.                   ld.blob_content,  
  143.                   SYSDATE,  
  144.                   confirm_upload.expiration_date,  
  145.                   confirm_upload.program_name,  
  146.                   confirm_upload.program_tag,  
  147.                   confirm_upload.LANGUAGE,  
  148.                   fnd_gfm.set_file_format(mt)  
  149.              FROM fnd_lobs_document ld  
  150.             WHERE ld.NAME = confirm_upload.file_name  
  151.               AND rownum = 1);  
  152.         
  153.         IF (SQL%ROWCOUNT <> 1) THEN  
  154.           RAISE no_data_found;  
  155.         END IF;  
  156.         
  157.         UPDATE fnd_lob_access  
  158.            SET file_id = fid  
  159.          WHERE access_id = confirm_upload.access_id;  
  160.         
  161.         IF wakeup THEN  
  162.           dbms_alert.signal('FND_GFM_ALERT' || to_char(access_id),  
  163.                             to_char(fid));  
  164.         END IF;  
  165.         -- bug 3045375, added else to return fid = -2.  
  166.       ELSE  
  167.         fid := -2;  
  168.       END IF;  
  169.       DELETE FROM fnd_lobs_document ld  
  170.        WHERE ld.NAME = confirm_upload.file_name;  
  171.       --delete from fnd_lobs_documentpart;  
  172.     END IF;  
  173.     RETURN fid;  
  174.   EXCEPTION  
  175.     WHEN OTHERS THEN  
  176.       DELETE FROM fnd_lobs_document ld  
  177.        WHERE ld.NAME = confirm_upload.file_name;  
  178.       --delete from fnd_lobs_documentpart;  
  179.       
  180.       err_msg('confirm_upload');  
  181.       RAISE;  
  182.   END;  
  183.   
  184.   PROCEDURE upload_file(p_file_name IN VARCHAR2, p_access_id IN NUMBER) IS  
  185.     l_file_id NUMBER;  
  186.   BEGIN  
  187.     
  188.     l_file_id :confirm_upload(access_id    => p_access_id,  
  189.                                 file_name    => p_file_name,  
  190.                                 program_name => g_package_name);  
  191.     
  192.     IF l_file_id NOT IN (-1, -2) THEN  
  193.       -- File upload completed  
  194.       htp.htmlopen;  
  195.       htp.headopen;  
  196.       htp.title('文件上传');  
  197.       htp.headclose;  
  198.       htp.bodyopen;  
  199.       htp.img2('/images/wwcban.jpg', calign => 'Center', calt => 'Logo');  
  200.       htp.br;  
  201.       htp.br;  
  202.       htp.p('<h4>' || '文件上传' || '</h4>');  
  203.       htp.hr;  
  204.       htp.p(htf.bold('文件上传完成。Select * from fnd_lobs flb where flb.file_id = ' ||  
  205.                      l_file_id));  
  206.       htp.br;  
  207.       
  208.       htp.p('<h4>' || '请关闭浏览器!' || '</h4>');  
  209.       htp.br;  
  210.       htp.bodyclose;  
  211.       htp.htmlclose;  
  212.       
  213.     ELSE  
  214.       -- File upload failed.  
  215.       htp.htmlopen;  
  216.       htp.headopen;  
  217.       htp.title('文件上传');  
  218.       htp.headclose;  
  219.       htp.bodyopen;  
  220.       htp.img2('/images/wwcban.jpg', calign => 'Left', calt => 'Logo');  
  221.       htp.br;  
  222.       
  223.       htp.hr;  
  224.       htp.p(htf.bold('文件上传失败!'));  
  225.       htp.br;  
  226.       htp.bodyclose;  
  227.       htp.htmlclose;  
  228.     END IF;  
  229.     
  230.   END;  
  231.   
  232.   PROCEDURE upload_cancel AS  
  233.     
  234.   BEGIN  
  235.     
  236.     -- Show a message page  
  237.     htp.htmlopen;  
  238.     htp.headopen;  
  239.     htp.title('取消文件上传');  
  240.     htp.headclose;  
  241.     htp.bodyopen;  
  242.     htp.img2('/images/wwcban.jpg', calign => 'Center', calt => 'Logo');  
  243.     htp.br;  
  244.     htp.br;  
  245.     htp.p('<h4>' || '文件上传' || '</h4>');  
  246.     htp.hr;  
  247.     htp.p(htf.bold('取消文件上传'));  
  248.     htp.br;  
  249.     htp.p('<h4>' || '您已经选择取消文件上传。' || '</h4>');  
  250.     htp.p('<h4>' || '请关闭浏览器!' || '</h4>');  
  251.     htp.br;  
  252.     htp.br;  
  253.     htp.br;  
  254.     htp.bodyclose;  
  255.     htp.htmlclose;  
  256.     
  257.   END;  
  258.   
  259.   PROCEDURE upload_form(p_access_id IN NUMBER DEFAULT NULL) IS  
  260.     l_upload_action VARCHAR2(2000);  
  261.   BEGIN  
  262.     
  263.     -- Set the upload action    
  264.     l_upload_action :fnd_gfm.construct_upload_url(g_agent,  
  265.                                                     g_upload_url,  
  266.                                                     p_access_id);  
  267.     -- Set page title and toolbar.  
  268.     htp.htmlopen;  
  269.     htp.headopen;  
  270.     htp.p('<SCRIPT LANGUAGE="JavaScript">');  
  271.     htp.p(' function processclick (cancel_url) {  
  272.                  if (confirm(' || '"' || '取消文件上传' || '"' || '))  
  273.                  {  
  274.                         parent.location=cancel_url  
  275.                  }  
  276.               }');  
  277.     htp.print('</SCRIPT>');  
  278.     htp.title('文件上传');  
  279.     htp.headclose;  
  280.     htp.bodyopen;  
  281.     htp.img2('/images/wwcban.jpg', calign => 'Center', calt => 'Logo');  
  282.     htp.br;  
  283.     htp.br;  
  284.     htp.p('<h4>' || '文件上传' || '</h4>');  
  285.     htp.hr;  
  286.     htp.br;  
  287.     htp.print('</LEFT>');  
  288.     
  289.     htp.formopen(curl     => l_upload_action,  
  290.                  cmethod  => 'POST',  
  291.                  cenctype => 'multipart/form-data');  
  292.     htp.tableopen(cattributes => ' border=0 cellpadding=2 cellspacing=0');  
  293.     htp.tablerowopen;  
  294.     htp.tablerowclose;  
  295.     
  296.     htp.tablerowopen(cvalign => 'TOP');  
  297.     htp.p('<TD>');  
  298.     htp.p('</TD>');  
  299.     htp.p('<label>文件</label>');  
  300.     htp.tabledata('<INPUT TYPE="File" NAME="p_file_name" SIZE="60">',  
  301.                   calign => 'left');  
  302.     htp.tablerowclose;  
  303.     htp.tableclose;  
  304.     
  305.     -- Send access is as a hidden value  
  306.     htp.formhidden(cname => 'p_access_id', cvalue => to_char(p_access_id));  
  307.     
  308.     htp.br;  
  309.     htp.tableopen(cattributes => ' border=0 cellpadding=2 cellspacing=0');  
  310.     htp.tablerowopen(cvalign => 'TOP');  
  311.     htp.tabledata('<INPUT TYPE="Submit" VALUE="' || '确定' ||  
  312.                   '" SIZE="50">',  
  313.                   calign => 'left');  
  314.     htp.tabledata('<INPUT TYPE="Button" NAME="cancel" VALUE="' || '取消' || '"' ||  
  315.                   ' onClick="processclick(''' || g_cancel_url ||  
  316.                   ''') " SIZE="50">',  
  317.                   calign => 'left');  
  318.     htp.tablerowclose;  
  319.     htp.tableclose;  
  320.     htp.formclose;  
  321.     
  322.     htp.bodyclose;  
  323.     htp.htmlclose;  
  324.   END;  
  325.   
  326.   PROCEDURE download_file(p_file_id   IN NUMBER,  
  327.                           p_access_id IN NUMBER,  
  328.                           p_purge     IN VARCHAR2 DEFAULT NULL) IS  
  329.   BEGIN  
  330.     fnd_gfm.download(p_file_id, p_access_id, p_purge);  
  331.   END;  
  332.   
  333.   PROCEDURE download_file_html(p_file_id   IN NUMBER,  
  334.                                p_access_id IN NUMBER,  
  335.                                p_purge     IN VARCHAR2 DEFAULT NULL) IS  
  336.   BEGIN  
  337.     htp.print('  
  338.     <html>  
  339.     <body>  
  340.       <img src=' || g_download_url || '?p_file_id=' ||  
  341.               p_file_id || chr(38) || 'p_access_id=' || p_access_id ||  
  342.               ' border=0>  
  343.     </body>  
  344.     </html>  
  345.     ');  
  346.   END;  
  347. END;  
  348. </span>/  

猜你喜欢

转载自blog.csdn.net/f_zhangyu/article/details/80344674