Saturday, June 24, 2017

Download Txt File from oracle database using Apex PL-SQL process

En este post , nosotros veremos como descargar archivos txt o cualquiera desde un proceso de  Apex Oracle.

En el ejemplo retornaremos el primer archivo de la tabla.

Adicionalmente crearemos este proceso en el before header y sera llamado con un submit desde la misma pagina.

Puede ver la demo aqui demo here   user: demo/ pass: demo

Dejo algunos enlaces fuente original del post, solo que aqui tengo el codigo mas simple posible para la ejecucion de este proceso.

Link1
Link2
Link3

Paso1: Crear un proceso After Header

declare 
    l_xml clob; 
    l_blob blob; 
    l_lang_context integer := DBMS_LOB.DEFAULT_LANG_CTX; 
    l_warning integer := DBMS_LOB.WARN_INCONVERTIBLE_CHAR; 
    l_dest_offset integer := 1; 
    l_source_offset integer := 1; 
    l_name varchar2(250);
begin
    dbms_lob.createtemporary(l_blob, true); 
begin 
    Select FILE_BLOB,FILENAME 
      into l_blob,l_name 
      from BLOG_FILES 
     where rownum = 1;
    exception when others then RETURN; 
    --apex_application.stop_apex_engine; 
    --owa_util.http_header_close; 
end; 
    /*if l_blob is null then return; end if;*/ 
    
    htp.init;
    -- Set the MIME typebranck
    owa_util.mime_header( 'application/octet-stream', FALSE,'UTF-8' );
    -- Set the name of the file 
    htp.p('Content-Disposition: attachment; filename="'||l_name||'"');
    owa_util.http_header_close; 
    --package that provides an interface to download files (BLOBs and BFILEs)
    wpg_docload.download_file( l_blob ); 
    --stop further processing and immediately exit
    apex_application.stop_apex_engine; 
    exception when others then
    htp.prn('error: '||sqlerrm); 
    apex_application.stop_apex_engine; 
end; 



Paso 2 crear un boton en la misma pagina con un submit y un request "DOWNLOAD" el mismo que sera usado como server side condition por el proceso afterHeader.






Share:

Friday, June 23, 2017

Show images from table / Carousel / Call Ajax / jQuery

Este ejemplo es muy util cuando tu necesitas trabajar con imagenes que se refresquen en cada momento.
Con este material puedes aplicar diferentes cambios de CSS para agrandar imagenes, poner etiquetas, cambiar el estilo de carrusel.

Este ejemplo esta basado en este original post, pero aqui he cambiado la forma para hacerlo mas dinamico y adicionalmente agrege una funcionalidad para que se pueda hacer el efecto de zoom en la imagen.

Puedes ver la demo aqui, user : demo / pass: demo

Estoy utilizando:
  1. Css
  2. JQUERY / jcarousellite de su fuente original o puedes descargar directamente desde aqui here.
  3. Ajax CallBack
  4. JavaScript
Primero necesitamos descargar el plugin y subirlo en los archivos estaticos, necesitamos el que dice jcarouselLite.min.js , puedes descargar las flechas desde aqui tambien. 




Crear un ItemGlobal de nombre: G_ID_FILE , cuidado con la sesion state



Crear un application processes de nombre : GET_IMG , pon este codigo, en el select cambialo por tu tabla de donde sacaras la imagen.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
DECLARE
  l_lob      BLOB;
  l_length   NUMBER;
  l_mimetype VARCHAR2(2000);
  l_filename VARCHAR2(2000);
BEGIN
--

SELECT PRODUCT_IMAGE
       ,mimetype
       ,filename 
  INTO l_lob,
       l_mimetype,
       l_filename  FROM DEMO_PRODUCT_INFO 
 WHERE  NVL(dbms_lob.getlength(PRODUCT_IMAGE),0) > 0  and PRODUCT_ID =  :G_ID_FILE;  
   
  --
  l_length := DBMS_LOB.getlength(l_lob);
  --
  htp.flush;
  htp.init;
  --
  owa_util.mime_header(nvl(l_mimetype,'application/octet'), FALSE);
 
  htp.p('Content-length:' || l_length);
  htp.p('Content-Disposition:inline;filename="' || l_filename || '"');
  --
  -- close the headers
  owa_util.http_header_close;
  --
  -- download the BLOB
  wpg_docload.download_file(l_lob);
--
END;






Ir a la pagina y en JavaScrip url, referencia al archivo estatico subido.




Colocar esto en Function and global variable declaration:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$('body').append('<div class="product-image-overlay"><span class="product-image-overlay-close">x</span><img src="" /></div>');
var productOverlay = $('.product-image-overlay');
var productOverlayImage = $('.product-image-overlay img');

function displayImagen (dir) {
    
    productOverlayImage.attr('src', dir);
    productOverlay.fadeIn(100);
    $('body').css('overflow', 'hidden');

    $('.product-image-overlay-close').click(function () {
        productOverlay.fadeOut(100);
        $('body').css('overflow', 'auto');
    });
}; 




En css inline

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
.carru{
    width: 85% !important;
} 
.clist{
 text-align:center;
 height:150px;
 width:140px;
 padding:2px;
 border: 0.3px solid #131313;
 margin: 5px;
}
#carousel-container{
 border:2px solid #CCC;
 background-color:#FFF;
 width:600px;
 float:left;  
}
#carousel-container li{
 list-style-image:none;
}
#carousel-container img{
 width:70px;
 height:80px;
} 
#carousel-prev,#carousel-next{
 display:block;
 float:left;
 text-decoration:none;
 height:160px;
 width:40px;
}
#carousel-prev{
 background: url("#APP_IMAGES#arrowl.gif") no-repeat scroll left 60px transparent;
}
#carousel-next{
 background: url("#APP_IMAGES#arrowr.gif") no-repeat scroll right 60px transparent;
} 



.product-image-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%; 
    background: rgba(251, 255, 255, 0.71);
    z-index: 9999;
    display: none;
}

.product-image-overlay .product-image-overlay-close {
    display: block;
    position: absolute;
    top: 20px;
    left: 20px;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 1px solid #fba3a3;
    line-height: 35px;
    font-size: 20px;
    color: #fbfbfb;
    text-align: center;
    cursor: pointer;
    background-color: #fd0000;
}


.product-image-overlay img {
    width: auto;
    max-width: 80%;
    position: absolute;
    top: 50%;
    left: 50%;
    -webkit-transform: translate(-50%, -50%);
    -moz-transform: translate(-50%, -50%);
    -o-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
}





Crear un region estandar con ID, header y footer como la imagen.




Crear un boton que llame una accion dinamica y luego un javaScriptCode, aqui esta la diferencia del origal post donde ellos usan un PlSql dynamic content. Pero aqui usare ajax para llamar al proceso que creare las veces que necesite.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
apex.server.process(
    "Refresh_image",
    {}, {
       dataType: 'text',
        success: function(data) {
           $('#carousel-container').html(data);
            console.log("dialog close");
            // alert("test")
        }
    }
); 

Note: "Refresh_image" es el nombre del proceso ajaxCallBack
           #carousel-container es el id, de tu region que creamos un paso anterior
            Console y alert, son solo de forma de prueba.
   


Crear un proceso ajax y colocar este codigo.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
DECLARE
  l_html varchar2(1000);
  l_img_src varchar2(1000);
BEGIN

  HTP.prn(' <ul style="margin: 0px; padding: 0px; position: relative; list-style: none; z-index: 1; width: 2800px; " >'); 
  FOR c1 IN( 
      SELECT PRODUCT_ID,
             filename
        FROM DEMO_PRODUCT_INFO
       WHERE NVL(dbms_lob.getlength(PRODUCT_IMAGE),0) > 0   order by filename asc
      
  )LOOP
 
 l_img_src := apex_util.prepare_url('f?p=' || :APP_ID || ':' || :APP_PAGE_ID || ':' || :APP_SESSION || ':APPLICATION_PROCESS=GET_IMG:NO::G_ID_FILE:' || c1.PRODUCT_ID);

 l_html := '<img  src="' || l_img_src || '">';     
    HTP.prn('<li style="overflow: hidden; float: left; cursor: pointer;" > ');            
    HTP.prn('<div  class="clist" onclick="displayImagen('''||l_img_src||''')" >' ); 
    htp.prn(l_html); 
    HTP.prn('<p>' || c1.filename || '</p>'); 
    HTP.prn('</div>'); 
    HTP.prn('</li>');  
  END LOOP;
    HTP.prn(' </ul>');  
       
        htp.p('<script type="text/javascript">');
            htp.p('$("#carousel-container").jCarouselLite({
            circular:false,
            visible:4,
            scroll:4,
            speed:300,
            btnPrev:"#carousel-prev",
            btnNext:"#carousel-next"
            });');
        htp.p('</script>');  
   
END;





Finalmente cuando des click en la imagen este tendra un efecto de zoom.



Demo aqui here, use user: demo / pass: demo







Share:

Install and Configure Oracle Application Express Apex 5.1.1,5.x with Embedded PL/SQL Gateway

Hi, for this first post i have compiled different tricks for install apex 5.1.1

Video en Español



First you can follow the original steps for Oracle... Install Apex from Oracle Page

But it will be summarized...

1: Download apex 5.1.1 from Oracle
2: Copy and compress the content in a directory easy access, for example D:\InstallApex
3: Open CMD and go for this directory and write SQLPLUS



4: Loged with  "sys as sysdba", enter your password and continue...
5: Run apexins.sql
@apexins.sql APEX APEX TEMP /i/
 or     @apexins.sql SYSAUX SYSAUX TEMP /i/

6: Once complete, change the admin password by running the "apxchpwd.sql" scripts as the SYS user.
@apxchpwd.sql
7: Create the APEX_LISTENER and APEX_REST_PUBLIC_USER users by running the "apex_rest_config.sql" script.
@apex_rest_config.sql

8: Run the Embedded PL/SQL Gateway configuration (EPG)
 @apex_epg_config.sql D:\InstallApex
   Note: You can try add "\" or erase it , The command automatically recognize the APEX main folder


9: Update APEX directory images with those from the new release, it could take a lot of minutes:
 @apxldimg.sql D:\InstallApex
10: Unlock the ANONYMOUS account.
          ALTER USER ANONYMOUS ACCOUNT UNLOCK;
      Note: Make sure that the following accounts are unlocked
ALTER USER xdb ACCOUNT UNLOCK;
ALTER USER apex_public_user ACCOUNT UNLOCK;
ALTER USER flows_files ACCOUNT UNLOCK;

11:  Aditional Config:
           11.1 Open XML DB Protocol Server.
 EXEC DBMS_XDB.sethttpport(8080); 
           11.2 Update quantity of process

            SHOW PARAMETER job_queue_processes
     ALTER system SET job_queue_processes=20 scope=both;

     SHOW PARAMETER shared_servers
     ALTER system SET shared_servers=5 scope=both;


             11.3 Enable remote HTTP connections (optional):

     EXEC dbms_xdb.setListenerLocalAccess(l_access => FALSE);



12:   APEX should now be available from a URL like http://127.0.0.1:8080/apex

13:   Granting Connect Privileges:

13.1   
     DECLARE

    ACL_PATH VARCHAR2(4000);

    BEGIN

    -- Look for the ACL currently assigned to '*' and give APEX_050100a

    -- the "connect" privilege if APEX_050100

    -- does not have the privilege yet.

    SELECT ACL INTO ACL_PATH FROM DBA_NETWORK_ACLS

    WHERE HOST = '*' AND LOWER_PORT IS NULL AND UPPER_PORT IS NULL;

    IF DBMS_NETWORK_ACL_ADMIN.CHECK_PRIVILEGE(ACL_PATH,     'APEX_050100',

    'connect') IS NULL THEN

    DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE(ACL_PATH,

    'APEX_050100', TRUE, 'connect');

    END IF;

    EXCEPTION

    -- When no ACL has been assigned to '*'.

    WHEN NO_DATA_FOUND THEN

    DBMS_NETWORK_ACL_ADMIN.CREATE_ACL('power_users.xml',

    'ACL that lets power users to connect to everywhere',

    'APEX_050100', TRUE, 'connect');

    DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL('power_users.xml','*');

    END;

    /

    COMMIT;

13.2
DECLARE
ACL_PATH  VARCHAR2(4000);
BEGIN
-- Look for the ACL currently assigned to 'localhost' and give APEX_050100
-- the "connect" privilege if APEX_050100 does not have the privilege yet.
SELECT ACL INTO ACL_PATH FROM DBA_NETWORK_ACLS
WHERE HOST = 'localhost' AND LOWER_PORT IS NULL AND UPPER_PORT IS NULL;
IF DBMS_NETWORK_ACL_ADMIN.CHECK_PRIVILEGE(ACL_PATH, 'APEX_050100',
'connect') IS NULL THEN
DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE(ACL_PATH,
'APEX_050100', TRUE, 'connect');
END IF;
EXCEPTION
-- When no ACL has been assigned to 'localhost'.
WHEN NO_DATA_FOUND THEN
DBMS_NETWORK_ACL_ADMIN.CREATE_ACL('local-access-users.xml',
'ACL that lets users to connect to localhost',
'APEX_050100', TRUE, 'connect');
DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL('local-access-users.xml','localhost');
END;
/
COMMIT;
14: For the first installation you need create a new schema and workspace. for this you can log in as ADMIN.

Workspace: INTERNALUsername: ADMINPassword: ***** 
   


Now you can enjoy of APEX









Share:

Subscribe to my Newsletter

Acerca de mi:

img

Ing. Angel O. Flores Torres, soy Ingeniero de Sistemas e Ingeniero de Aplicaciones Oracle Apex, he trabajado con Oracle Apex 5 y 5.1 desde el 2017, En los ultimos años he desarrollado habilidades en CSS, JavaScript, Jquery y PlSql , I specialize in Oracle APEX (Oracle Application Express )

Followers

Popular Posts