Discussions
Categories
- 385.5K All Categories
- 5.1K Data
- 2.5K Big Data Appliance
- 2.5K Data Science
- 453.4K Databases
- 223.2K General Database Discussions
- 3.8K Java and JavaScript in the Database
- 47 Multilingual Engine
- 606 MySQL Community Space
- 486 NoSQL Database
- 7.9K Oracle Database Express Edition (XE)
- 3.2K ORDS, SODA & JSON in the Database
- 585 SQLcl
- 4K SQL Developer Data Modeler
- 188K SQL & PL/SQL
- 21.5K SQL Developer
- 46 Data Integration
- 46 GoldenGate
- 298.4K Development
- 4 Application Development
- 20 Developer Projects
- 166 Programming Languages
- 295K Development Tools
- 150 DevOps
- 3.1K QA/Testing
- 646.7K Java
- 37 Java Learning Subscription
- 37.1K Database Connectivity
- 201 Java Community Process
- 108 Java 25
- 22.2K Java APIs
- 138.3K Java Development Tools
- 165.4K Java EE (Java Enterprise Edition)
- 22 Java Essentials
- 176 Java 8 Questions
- 86K Java Programming
- 82 Java Puzzle Ball
- 65.1K New To Java
- 1.7K Training / Learning / Certification
- 13.8K Java HotSpot Virtual Machine
- 94.3K Java SE
- 13.8K Java Security
- 208 Java User Groups
- 25 JavaScript - Nashorn
- Programs
- 667 LiveLabs
- 41 Workshops
- 10.3K Software
- 6.7K Berkeley DB Family
- 3.6K JHeadstart
- 6K Other Languages
- 2.3K Chinese
- 207 Deutsche Oracle Community
- 1.1K Español
- 1.9K Japanese
- 474 Portuguese
Dynamically displaying PDF in a region

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...
... 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):
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!
Best Answer
-
So, I have found a solution for the problem. I am shocked at how little information there is regarding how to set this up, since it seems like a pretty common use-case to me.
Regardless, here is a step-by-step tutorial:
Fully-Functional, dynamically loaded PDF Viewer in Oracle APEX
This Tutorial explains how you can build and implement an easy PDF Viewer in Oracle Apex utilizing Guidelines by PDFObject to fully support current browsers as well as Apex's RESTful Services for Data Delivery. The tutorial makes use of newer Web APIs such as Fetch, which might be exchanged with
XMLHttpRequest
. The browser should also support Blobs.The documentation is based on the
Sample File Upload and Download
which can be installed using the App GalleryThe HTML
After getting into the Application Builder open the page you want your PDF Viewer to be in (in this tutorial it is Page 3 - Files):
After opening the Page Select where you want to place your PDF Viewer, in our case it is below the rest of the content, therefore we create a subregion in one of the parent containers of the page:
We call it PDF Viewer for simplicity:
Leave the Object as Type
Static Content
. In the source paste the following Code:<div id="pdfViewer" style="width: 100%; height: 500px"> <iframe src="" style="border: none;" type="application/pdf" width="100%" height="100%"></iframe></div>
We are adhering to the implementation of PDFObject found at the very bottom of this page: https://pdfobject.com/static
Both the
id
and thestyle
attribute for the top leveldiv
container can be changed, but keep in mind that this has to be carried over to later parts of the tutorial as well. This tutorial will use the values seen here.The Region Window should now look something like this:
The Javascript
Next up we have to add a few Javascript Statements to ensure that the RESTful Service that will be implemented later is called correctly.
First up we will create a dynamic action to trigger the RESTful service and to act as a link between the user interaction and the service.
For that select the Dynamic Actions Tab Item in the Application:
Right-click on Event and create a new Action:
As
Identification
we will usePDFViewer
for simplicity. In theWhen
Block change theEvent
type toCustom
(at the very bottom of the list). A new Input Bar should appear that asks for aCustom Event
, which we will callPDFViewer
as well. AsSelection Type
selectJavaScript Expression
. In theJavascript Expression
Textbox enterdocument
.This should look something like this:
Next step is to go into the True Block:
In the
Identification
Block change the Value ofAction
toExecute JavaScript Code
In the
Settings
Block below change the Value ofCode
to the following:let id = this.data.id;async function getData(){ let afetch = await fetch(`http://localhost:8080/ords/obe/pdf/pdfs/${id}`); let blob = await afetch.blob(); let blobUrl = URL.createObjectURL(blob); let pdfContainer = document.getElementById('pdfViewer'); pdfContainer.getElementsByTagName('iframe')[0].src = blobUrl;}getData();
The rest can be left as is.
This should now look something like this:
As we are using the
Sample File Upload and Download
we have a table with all the PDFs in the database. We are going to edit the current link to the details of the document (placed on the Filename Column) to reflect a call to a dynamic action that we created earlier. For that scroll to theLink
block and change theTarget
value to:Type
:URL
javascript:apex.event.trigger(document, 'PDFViewer', [{id:'#ID#'}]);
void(0);PDFViewer
is the Dynamic Action we created earlier
The RESTful Service
The last step is to create a RESTful Service. You do that by going to the RESTful Services Page
If you see something like this register the schema, keep the default values:
Create a new Module:
We are using a very simple Module for gathering the PDF which we call
PDFViewer
and usepdf
asBase Path
.Clicking on Create you will get the following menu:
Scroll down to
Create Template
and press the button:Click
Create Handler
:Here you have the change the
Source Type
add theSource
:SELECT FILE_MIMETYPE, FILE_BLOBFROM EBA_DEMO_FILESWHERE ID = :id
Please change the Select Statement accordingly. You need the mimetype as well as blob as return statement. After that press Create Handler.
The view on the left side should look like this now:
Running the application will look like this:
Answers
-
-
Unfortunately, this is not a suitable solution. As I have mentioned, something like ApexPDFRenderer which, just like your example, provides no functionality beyond going from page to page, is not
what I am looking for.
What I need is a fully functional PDF-Viewer, like the one browser use by default
https://stackoverflow.com/questions/14081128/how-to-embed-a-pdf-viewer-in-a-page
The problem lies with dynamically getting the .pdf-file from the database. Meaning: I can change the contents of the PDF-viewer below the IR by clicking on different elements in the IR, and the page will not reload.
https://joelkallman.blogspot.com/2014/03/yet-another-post-how-to-link-to.html
I am currently trying to get this approach to work, without much success...
-
You can make a demo and post the workspace/username/password here. We will take a look at it and
help you to make it works.
-
So, I have found a solution for the problem. I am shocked at how little information there is regarding how to set this up, since it seems like a pretty common use-case to me.
Regardless, here is a step-by-step tutorial:
Fully-Functional, dynamically loaded PDF Viewer in Oracle APEX
This Tutorial explains how you can build and implement an easy PDF Viewer in Oracle Apex utilizing Guidelines by PDFObject to fully support current browsers as well as Apex's RESTful Services for Data Delivery. The tutorial makes use of newer Web APIs such as Fetch, which might be exchanged with
XMLHttpRequest
. The browser should also support Blobs.The documentation is based on the
Sample File Upload and Download
which can be installed using the App GalleryThe HTML
After getting into the Application Builder open the page you want your PDF Viewer to be in (in this tutorial it is Page 3 - Files):
After opening the Page Select where you want to place your PDF Viewer, in our case it is below the rest of the content, therefore we create a subregion in one of the parent containers of the page:
We call it PDF Viewer for simplicity:
Leave the Object as Type
Static Content
. In the source paste the following Code:<div id="pdfViewer" style="width: 100%; height: 500px"> <iframe src="" style="border: none;" type="application/pdf" width="100%" height="100%"></iframe></div>
We are adhering to the implementation of PDFObject found at the very bottom of this page: https://pdfobject.com/static
Both the
id
and thestyle
attribute for the top leveldiv
container can be changed, but keep in mind that this has to be carried over to later parts of the tutorial as well. This tutorial will use the values seen here.The Region Window should now look something like this:
The Javascript
Next up we have to add a few Javascript Statements to ensure that the RESTful Service that will be implemented later is called correctly.
First up we will create a dynamic action to trigger the RESTful service and to act as a link between the user interaction and the service.
For that select the Dynamic Actions Tab Item in the Application:
Right-click on Event and create a new Action:
As
Identification
we will usePDFViewer
for simplicity. In theWhen
Block change theEvent
type toCustom
(at the very bottom of the list). A new Input Bar should appear that asks for aCustom Event
, which we will callPDFViewer
as well. AsSelection Type
selectJavaScript Expression
. In theJavascript Expression
Textbox enterdocument
.This should look something like this:
Next step is to go into the True Block:
In the
Identification
Block change the Value ofAction
toExecute JavaScript Code
In the
Settings
Block below change the Value ofCode
to the following:let id = this.data.id;async function getData(){ let afetch = await fetch(`http://localhost:8080/ords/obe/pdf/pdfs/${id}`); let blob = await afetch.blob(); let blobUrl = URL.createObjectURL(blob); let pdfContainer = document.getElementById('pdfViewer'); pdfContainer.getElementsByTagName('iframe')[0].src = blobUrl;}getData();
The rest can be left as is.
This should now look something like this:
As we are using the
Sample File Upload and Download
we have a table with all the PDFs in the database. We are going to edit the current link to the details of the document (placed on the Filename Column) to reflect a call to a dynamic action that we created earlier. For that scroll to theLink
block and change theTarget
value to:Type
:URL
javascript:apex.event.trigger(document, 'PDFViewer', [{id:'#ID#'}]);
void(0);PDFViewer
is the Dynamic Action we created earlier
The RESTful Service
The last step is to create a RESTful Service. You do that by going to the RESTful Services Page
If you see something like this register the schema, keep the default values:
Create a new Module:
We are using a very simple Module for gathering the PDF which we call
PDFViewer
and usepdf
asBase Path
.Clicking on Create you will get the following menu:
Scroll down to
Create Template
and press the button:Click
Create Handler
:Here you have the change the
Source Type
add theSource
:SELECT FILE_MIMETYPE, FILE_BLOBFROM EBA_DEMO_FILESWHERE ID = :id
Please change the Select Statement accordingly. You need the mimetype as well as blob as return statement. After that press Create Handler.
The view on the left side should look like this now:
Running the application will look like this:
-
Thank you for the tutorial. That will work in Chrome and Firefox, but Edge won't display the PDF toolbar if you load the PDF in an iframe. Those users won't have a "fully functional PDF-Viewer, like the one browser use by default".
jayp941 wrote:I am shocked at how little information there is regarding how to set this up
https://www.google.com/search?q=oracle+apex+pdf+preview
> "Oracle Apex - PDF Display" [Oct 9, 2018]
> [Using <embed> ]
> "Oracle Apex PDF Viewer" [Oct 26, 2018]
> https://apex.oracle.com/pls/apex/f?p=34781 (using an On Demand process + pdf.js +)
https://www.google.com/search?q=oracle+apex+iframe+pdf
> "displaying contents of a pdf on a region" [Aug 9, 2006]
https://www.google.com/search?q=oracle+apex+blob+url
> "Download a BLOB image as file, how?" [Sep 13, 2016]
> "Yet Another Post How to Link to Download a File or Display an Image from a BLOB column" [March 20, 2014] "It's definitely easier to implement via a RESTful Service, and ... will always be much faster.... However, one benefit of doing this via an On Demand process is that it will also be constrained by any conditions or authorization schemes that are in place for your APEX application"
> "Using RESTful to deliver Images for APEX" [July 24, 2013]
-
Hi,
https://www.youtube.com/watch?v=cyN6rrawd74
Please follow this video to the show table store pdf into a particular region.
-
I run APEX 21.2 and followed your tutorial, but it is not working.
I can see following error in console.log
DevTools failed to load source map: Could not load content for http://localhost:8080/i/libraries/apex/minified/ojtimezonedata.js.map;: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE
I also went to find ojtimezonedata.js.map, but there is no such file in this dir.
-
Hello,
I'm running APEX 21.1 and I followed every step but when i click on the filename to render the pdf i get the following error on the static region
The request could not be processed because an error occurred whilst attempting to evaluate the SQL statement associated with this resource. Please check the SQL statement is correctly formed and executes without error. SQL Error Code: 1722, Error Message: ORA-01722: invalid number
-
Thank you very much for the answer and complete explanation, the procedure works very well and is displayed without any problem in both Chrome and Microsoft Edge 👍️
According to my version of Rest and APEX, I changed the API a bit, but it was minimal.
::
Muchas gracias!!
Thank you very much..