Question

How to display PDF in Section?Invoice

User Story: We have to display Invoice in PDF format in Section.

We are creating case from inbound EMail, contains invoince in PDF format as attachment.

Client don't want to click attachment link to open the invoice attached to case in new window. Instead invoice should be displayed as part of case UI.

Thanks in Advance!

Thabks & Regards

U Rajasekhar

***Updated by moderator: Lochan to add Categories***

**Moderation Team has archived post**

This post has been archived for educational purposes. Contents and links will no longer be updated. If you have the same/similar question, please write a new post.

Correct Answer
May 4, 2018 - 5:33am

Additionally - does the Data Transform example above (for video files) not help you here ?

Comments

Keep up to date on this post and subscribe to comments

November 28, 2016 - 1:08pm

Hello U Rajasekhar,

I have never done something like this, but if I were you, I'd start by using the OOTB attachment code which provides you a link to display the PDF and trace the request when you click on it. I'm not sure what you can make of that, since I'm pretty sure it has you download the attachment, but it would be a starting point.

Thanks,

Mike

November 29, 2016 - 9:33am
Response to MikeTownsend_GCS

Hi Mike,

We have already discussed about OOTB, but client wants to display PDF in bottom part of Case UI.

Thanks

U Rajasekhar

November 28, 2016 - 10:19pm

Hi Rajasekhar,

I believe PDF can be included as on object inside HTML for viewing purposes. You may create a non auto generated section and write the code to embed pdf attached to case. And make this section appear when clicked on the link to download the attachment.

Refer to the below link.

https://pdfobject.com/static.html

November 29, 2016 - 9:36am
Response to Shashidhar_Palle

Hi Shashidhar,

I have tried it is not displaying. As soon as open case with embbed PDF, it download. It does not display.

Are you able to display?

Thanks

U Rajasekhar

November 28, 2016 - 11:47pm

Leverage "embed/iframe" tag to achieve this, i think it will well suit for your requirement. Try out and keep posted.

November 29, 2016 - 9:37am
Response to ChandruR

Hi Chandra, 

I have tried it is not displaying. As soon as open case with embbed PDF, it download. It does not display.

Are you able to display?

Thanks

U Rajasekhar

December 6, 2016 - 8:45am
Response to Prudhvi_N

Hi Prudhvi,

I have gone through above links and it is not working. Do you have any solution.

Thanks

U Rajasekhar

December 20, 2016 - 12:45pm
Response to RajasekharU0829

Please share the solution.............

Pega
December 21, 2016 - 1:09am

Hi Rajasekhar,

Try to use View Activity from Code-Pega-PDF Class.

pass the bytearray in PDFDocument parameter.

Also check the below link. 

Link: https://pdn.pega.com/community/pega-product-support/question/converting-section-pdf

December 30, 2016 - 5:30am
Response to Prudhvi_N

Hi Prudhvi,

We are trying to display a PDF already attached to the case.

Our query is have to display a PDF in Work information section?

Happy New Year!

Thanks & Regards

U Rajasekhar

Pega
January 11, 2017 - 3:27am

Hi Rajasekhar,

The below link may help you.

https://pdn.pega.com/community/pega-product-support/question/custom-pdf-viewer-pega

Thanks and Regards,

Prudhvi Ranjan

January 23, 2017 - 4:17am
Response to Prudhvi_N

Hi Prudhvi,

We tried approach mention in "Custom pdf viewer in pega" url. It is not working.

Thanks & Regards

U Rajasekhar

Pega
January 23, 2017 - 1:32pm

I have managed to cobble together a basic Proof-of-concept using PRPC722 of what I believe you want here.

The main 'trick' here is to create a SECTION and untick 'Auto-generated HTML' and put an 'object' tag in there which calls a PRPC Activity (included below also) to display the bytes of a PDF (actually, it works for other filetypes as well - although no all) in a separate browser window - rather than launching an external PDF viewer, or prompting the user to save.

Note: this will probably NOT work for CMIS or other Attachment mechanisms; only ones stored internally in PRPC.

Here's the HTML/JSP code that does creates the'object' : this is called 'Link-Attachment.InLineAttachment'.

(Most of the stuff we are creating is NOT at the WORK CLASS: it is at the 'Link-Attachment' layer):

  1. <html>
  2. <head>
  3. <title>Display Attachment inline</title>
  4. <style type="text/css">
  5. //bad idea to put CSS in here probably - PRPC will be applying styles of its own.
  6. object.inline { border: 1px solid;}
  7. </style>
  8. </head>
  9. <body>
  10. <%
  11. %>
  12. <object class="inline" data="<pega:url value='pyActivity=Link-Attachment.ShowAttachment&pxLinkedRefTo='/><p:r n='.pxLinkedRefTo'/>"
  13. width="800" height="600" type="<p:r n='.CalculatedMimeType'/>" </object>
  14. </body>
  15. </html>

So to start with : I created a new Application (using standard OOTB tools); created a Section and included that in my Flow. (This is pretty much the only rule which is built at this my Work Pool level).

This doesn't do much except define a Grid to show us a List of Attachments (this is mainly for testing purposes):

The 'Action' Defined on the 'Open it' Link Column is a 'List' Type ("Open Local Action") , as can be seen in the screenshot below:

This calls a Flow Action called 'Link-Attachment.ShowInLineAttachments'; which in turn references the Section (the code of which is above).

 

This is what the solution looks like at Runtime:

I have displayed this in a MODAL window - but that should be easier enough to change.

Here's the Activity (Again, as 'Link-Attachment') which does the job of finding the Attachment Data and Streaming back to the client. (The 'object' tag in the Section above runs this Activity).

There is one Parameter (type: String)

pxLinkedRefTo

There are three Local Variables (type: String):

pxLinkedRefTo, pxAttachName, pyAttachStream

One Page, 'AttachmentData' of type 'Data-WorkAttach-File'.

And since we are calling this 'indirectly' via a URL ; we need to check the option 'Allow direct invocation from the client or service' (on the Security Tab).

The Steps are as follows (pseudo-code; saves me taking a load of screenshots - I hope this is understood).

  1. #1: Log-Message(Param.pxLinkedRefTo, infoForced)
  2. #2: Property-Set(Local.pxLinkedRefTo<-Param.pxLinkedRefTo)
  3. #3: Page-New(AttachmentData)
  4. #4: Obj-Open-By-Handle(Page=AttachmentData,InstanceHandle="Local.pxLinkedRefTo")
  5. #5: Property-Set(local.pxAttachName<-.pxAttachName, local.pyAttachStream <-.pyAttachStream)
  6. #6: Page-Remove(AttachmentData)
  7. #7: Java Step: (below)
  1. byte[] byteArray=Base64Util.decodeToByteArray(pyAttachStream);
  2. String result=tools.sendFile(byteArray, pxAttachName, false, null, false );

 

 

(actually: There is no need for the 'Param->Local' step (for 'pxLinkedRefTo') - I had this for a different (failed) approach - the Activity can actually be simplified).

There is one other awkard implementation detail here (there is probably a better way of doing this).

Since the 'object' tag (at least purports to) require a 'mime-type': we added a new Property and a Declare Expression to calculate this given the Attachment Name:

At 'Link-Attachment' ; created a (Text) Property called "CalculatedMimeType", and a corresponding DECLARE EXPRESSION of the same name; which uses the (OOTB) Function "pxGetMimetypeFromFileName" (which infers a MIME TYPE given a filename):

Note: the 'Change Tracking' had to be set up as follows:

Calculate Value: Whenever used.

Execute this expression:

when the top-level page is of the Applies To class, or one of the following.

Allowed Top-Level Classes

<My Work Pool>

So putting this together, we are able to attach items to Work Items/Cases in the standard way; but able to launch them using an 'object' tag - which gives us more control over how the browser presents this to the user.

See the Pega Engine Class javadocs regarding the options available for 'sendFile'.

I hope this is more or less what you needed here; the main 'custom' bits can be seen to be the non-auto generated Section Rule and the Activity - everything is reasonably OOTB PRPC stuff; and you should be able to make minor adjustments without further customization (like how to display the PDF in a non-modal window etc).

Thanks,

John

Additionally: I have 'rapped' this up.

You can get it from the attachment.

(PRPC722; it *might* work on earlier V7 PRPCs as well, but I haven't tried that).

***Moderator Edit-Vidyaranjan: Removed Box url and updated content***

 

January 24, 2017 - 9:11am

John's approach is pretty slick. But if you have some mechanism to base64 encode your PDF through some utility/activity and save that value, you could in theory create your own custom control/non-autogenerated section to use the newer HTML5 <EMBED> tag. Then you'd plop your base64 encoded value for the source. Take a look at this proof of concept.

test.pdf is the source PDF

rettTest.txt, rename to .html and invoke that in a browser to see it in action.

 

Pega
January 24, 2017 - 9:28am
Response to Rett_Hean_GCS

Thanks Rett: just a note about the 'embed' versus 'object' tag - I was under the impression that 'object' was a standard HTML element, whereas 'embed' was an older (Netscape innovation) element...but I find contradictory evidence on the web about this (see: http://stackoverflow.com/questions/1244788/embed-vs-object).

But I see the main difference here is that you are 'inlining' the data of the object in the page: which I (again, I could be wrong) don't believe the 'object' tag supports: which gives a nice advantage of being able to generate the whole thing in one go. 

There are some possible disadvantages of 'inlining' as well : issues with Chrome have been found (see: https://productforums.google.com/forum/#!topic/chrome/428NG5agplI) ; and also 'inlining' the data is base64 can 'bloat' your HTML quite significantly.

But good to have the choice of both ways of doing this.

Cheers !

John

 

 

January 24, 2017 - 3:04pm
Response to JOHNPW_GCS

That's correct John, thanks, and my understanding as well. Historically the embed tag was non-standard and not officially recognized by HTML4. Each browser may choose to honor it or handle it how they wished.

It wasn't until HTML5 when it was officially added to the HTML spec.

And yes, my approach will significantly "bloat" the HTML :)

Pega
January 24, 2017 - 9:31am

Also (quite unexpectedly and totally unintentionally !) I discovered today - that the solution (the one I gave, but possibly could work with Rett's as well?) above has a quite a nice feature - in that the 'next', 'previous' buttons on the Modal window have the nice effect of allowing you to 'browse' the attachments in a sort-of 'preview' mode.

I guess the 'next' and 'previous' buttons are activating the 'Action' on the Grid - a nice feature that I knew nothing about !

 

Pega
January 25, 2017 - 5:07am

Just an aside : here's (what I believe to be) an improvement to the original HTML posted here for the Section "inLineAttachment" ; it just removes the 'width/height' attributes from the Object Tag if the attachment is an image type; this then makes the browser (I only checked Chrome here though) scale the image in it's original format.

(I also made this a HTML fragment - rather than a full HTML document, which is also probably the right thing to do here).

  1. <pega:choose>
  2. <pega:when java='<%= tools.getStepPage().getString("CalculatedMimeType").contains("image")%>'>
  3. <object class="inline" data="<pega:url value='pyActivity=Link-Attachment.ShowAttachment&pxLinkedRefTo='/><p:r n='.pxLinkedRefTo'/>"
  4. type="<p:r n='.CalculatedMimeType'/>" </object>
  5. </pega:when>
  6. <pega:otherwise>
  7. <object class="inline" data="<pega:url value='pyActivity=Link-Attachment.ShowAttachment&pxLinkedRefTo='/><p:r n='.pxLinkedRefTo'/>"
  8. width="800" height="800" type="<p:r n='.CalculatedMimeType'/>" </object>
  9. </pega:otherwise>
  10. </pega:choose>

 

 

May 3, 2018 - 9:52pm
Response to JOHNPW_GCS

Hi John,

This is working fine for Images, but PDF are not loaded in chrome and IE.

Seems below code is working

byte[] byteArray=Base64Util.decodeToByteArray(pyAttachStream);
String result=tools.sendFile(byteArray, pxAttachName, false, null, false );

I see tools.sendFile(byteArray, pxAttachName, false, null, false ); is returning null for success as per Engine API

and this is working for Images too as I was able to see the images rendered inline in modal window.

Seems object tag has issues in chrome and IE did you face any issues

Chrome :

For Acrobat reader plugin in chrome it is giving me error unable to load PDF

For PDF Viewer plugin I see message stream must have data.

IE:

Error : File does not belong with '%PDF-

If you faced this issue can you let me know how you resolved this.

Pega
May 4, 2018 - 5:35am
Response to Gopi_P_Incessant

The error *suggests* that perhaps the file data isn't being sent at all ?

Maybe try adding an oLog.debug in the JavaStep just before the 'sendFile' - and make sure the 'byteArray' is populated. (Just check the size of the array - >0 ?)

 

May 4, 2018 - 6:38am
Response to JOHNPW_GCS

Thank you John.

I realized just now my PDF files has not upload properly seems all these pdf are uploaded with zero bytes.

Pega
January 27, 2017 - 12:46pm

I have added some other features to this App - so you can now convert HTML attachments dynamically to PDF, and you can Extract Text From a PDF.

I have also got rid of the Declarative Expression that was used to calculate the MimeType; using an explicit Data Transform now. (Probably a bit easy for other people to see how it fits together this way?); you may find you have 'submit' the form to get the DT to run - depending on what part of the Flow you are on. (I'm still working on why this is).

Find the file in the attachment.

Here's the Text Extractor Working:

***Moderator Edit-Vidyaranjan: Removed Box url and updated content***

Pega
January 27, 2017 - 1:02pm

The other advantage of using a Data Transform rather than a Declarative Expression - is that you can extend with more wordy logic.

For instance: I noticed that the Mime Type for 'webm' was being set to a generic 'binary' type - which means the browser (I'm using Chrome here) didn't see it as a video.

So: this can be corrected like this:

Now the video has the correct Mime Type :

And clicking the 'Open It' link will now play the video inline:

February 1, 2017 - 4:12am
Response to JOHNPW_GCS

Hi Jhon,

I tried import to 721, and successfully import. But, when I change my primary Access Group to "Pdf:Administrators" I cannot login​ "Unable to authenticate ......: No such Rule-Application instance: UIKit:08.01". How it can be?

Can you create an attachment file where it's content is step by step to recreate the application? 

Thanks and Regards,

Alfian

Pega
February 2, 2017 - 4:54am
Response to dorkyark

Hi Alfian,

The RAP file was from a 722 system - so I guess the pre-reqs are not present on your 721 system.

Do you have access to a 722 system to try this ? ('Personal Edition' even ?)

If you don't : try opening up the imported Application Rule on your system - and are you able to see the dependency on 'UIKit:08.01' - and able to modify it for the equivalent 721 system ?

(I haven't tried this yet; so sorry not to be able to provide explicit instructions here).

If I get chance; I'll see if I can refactor the app on a 721 system.

Thanks,

John

 

January 1, 2018 - 10:40am
Response to JOHNPW_GCS

Hi John,

Wishing u a very happy new year.

Thank you for sharing the code in the pegabox. 

I have a slightly different requirement. I am trying to view the image/pdf triggered from a data class. I am able to update the Activity, section and flowaction. Standalone Activity is working fine. Able to view the attachment. However, when i call the same activity from the section by invoking a flowaction(as mentioned above), unable to invoke the activity, I am getting a blank popup. Can u please provide pointers?

Thank you!!

Pega
May 4, 2018 - 5:29am
Response to Bukhari474

Try running a FIDDLER or other HTTP 'sniffer' - and do you see the base64 of the PDF being sent back to the client or not ? (Add some DEBUG lines to your java steps as well - perhaps check the length of the byteArray is >0 etc.) - this might be more to do with picking up the correct parameters/properties etc , rather than an issue with sending the file per say ?

April 20, 2018 - 3:45am

Hi , I want to MIME type for eml format.This functionality not working in chrome for eml messages.

Can anyone help on this?

Pega
May 4, 2018 - 5:32am
Response to kumarS3149

I think this deserves a separate post to enable a new discussion about MIME types - it would be good if you could provide (screenshots whatever helps) and example of what does happen here ? (Is this an issue with the 'sendFile' API not setting up a MIME type for '.eml' ? etc?)

(I'm not sure what the MIME type for '.eml' files are actually ? Is it a Microsoft-specific one I wonder ?)

Pega
May 4, 2018 - 5:33am
Response to JOHNPW_GCS

Additionally - does the Data Transform example above (for video files) not help you here ?