Skip to Main Content

APEX

Dynamically displaying PDF in a region

jayp941Oct 15 2019 — edited Oct 18 2019

Hello,

I am relatively new to Apex, and I have been trying to solve this problem for the last few days on and off, with no actual results. So I have decided to ask the experts here for help.

So what I am going to have in this part of the application (I am testing in an isolated mock-environment) is an Interactive Report filled with files (mostly .pdf).

The goal is to have a region on the same page, which displays the currently selected pdf using the browsers PDF viewer (this makes ApexPdfRenderer unsuitable, since it only loads the pages of the pdf as images and provides pagination).

Now, as you can see, I am somewhat close to solving this, yet farther away than ever before.  What I have done so far:

1. Created a Dynamic Action and bound it to the file_name - link. It contains the following js-code:

console.log('this', this);

var id = this.data.id;

console.log(id);

function getData() {

    let result;

console.log(apex.server);

    apex.server.process(

        "download_my_file", //PL/SQL Procedure (See 2)

        { x01: id }, //ID of the file

        {

            dataType: 'text', //Using anything else than json or html return an error (for JSON: "SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data")

            async: false,

            success: (pData) => {

                console.log(pData);

                let blob = new Blob([pData], {type: 'application/pdf'});

                console.log(blob);

                document.getElementById('pdf').src = URL.createObjectURL(blob);

                result = blob;

            }

        }

    );

    return result;

}

getData();

2. download_my_file is a Process/Ajax-Callback...

pastedImage_4.png

... Which executes the following PL/SQL Procedure:

CREATE OR REPLACE PROCEDURE download_my_file(p_file in number) AS 

    v_mime  VARCHAR2(48); 

    v_length  NUMBER; 

    v_file_name VARCHAR2(2000); 

    Lob_loc  BLOB; 

BEGIN 

    SELECT FILE_MIMETYPE, FILE_BLOB, filename, DBMS_LOB.GETLENGTH(file_blob) 

INTO

    v_mime,lob_loc,v_file_name,v_length 

FROM EBA_DEMO_FILES 

WHERE id = p_file; 

-- 

-- set up HTTP header 

-- 

-- use an NVL around the mime type and 

-- if it is a null set it to application/octect 

-- application/octect may launch a download window from windows 

owa_util.mime_header( nvl(v_mime,'application/octet'), FALSE ); 

-- set the size so the browser knows how much to download 

htp.p('Content-length: ' || v_length); 

-- the filename will be used by the browser if the users does a save as 

htp.p('Content-Disposition:  inline; filename="'||replace(replace(substr(v_file_name,instr(v_file_name,'/')+1),chr(10),null),chr(13),null)|| '"'); 

-- close the headers            

owa_util.http_header_close; 

-- download the BLOB 

wpg_docload.download_file( Lob_loc ); 

end download_my_file;

The result of all of this is a pdf being loaded into the specified region when the filename is clicked. However, all pages are blank. Yet, the number of pages is correct. The console shows the following errors (Firefox):

pastedImage_7.png

Altough there are a lot of resources for this problem on the Internet, most of them either

A. Use a static approach instead of a dynamic one

B. Contradict themselves

C. Only work with some browsers

D. All of the above

So I am now looking for a definitive answer to this problem. I feel like I am very close to achieving it, yet the way I am doing it doesn't seem to be the most efficient one. So I have come here, looking for guidance.

Thank you in advance!

This post has been answered by jayp941 on Oct 16 2019
Jump to Answer
Comments
Post Details
Added on Oct 15 2019
10 comments
8,953 views