7

I have pdf blob data returning in my webservice.. I want to display this blob data as pdf in visualforce page. Is there any way to render the page as pdf with this blob data looking like pdf page. Currently, it is printing the base64 encoded string in the pdf page. But I want to convert pdf blob base64 encoded data as true pdf page

<apex:page renderAs="pdf">
     {!pdfBlobData}
</apex:page>

Please correct me if I am wrong or suggest me a way to display this.

  • can you post/Suggest how you solved the above issue? Facing the Same issue – SFDC Apr 26 '19 at 10:35
2

Visualforce does not emit binary data. As such, there is no direct way I'm aware of to render a PDF blob to the user using Visualforce.

The one semi-exception I know of is that you can cause a browser to render an image file (not PDF) using base 64 data URL's.

Your best bet is probably to save the PDF blob as an Attachment object, and then redirect the user to the "View Attachment" platform URL.

| improve this answer | |
  • Yeah that's true.. But I need to find a solution to make this happen. Any other way I should be looking for? – NoNicknameSFDC Apr 29 '15 at 6:46
0

Summary of your situation

I try to understand the issue in general. A web service returns a blob of data, which is actual a pdf. The pdf should be presented to the user as a pdf.

Potential solutions

Store the PDF Blob as an attachment

  1. Download the PDF from your web service and store the received blob as attachment.
  2. Redirect the user on your VF Page to the generated attachment.

Use Javascript to present the pdf blob

On your visual force page include the blob via Javascript as a new object.

var content = URL.createObjectURL(blob); // your Blob
$("embed").attr("src", content); // add the blob to your VF page
<embed src="" width="200" height="200"></embed>
| improve this answer | |
0

Although this post is old, I came across the same problem and found a solution. As @jkraybill mentioned above, Visualforce will not emit binary data. This means we can't retrieve a Blob from Salesforce to our client. A solution to this problem is to change the controller getter to return a (Base64) String and convert it to a Blob via Javascript, then load the Blob as a PDF. A good post explaining how to convert Base64 to a Blob can be found here. I recommend reading that post as it goes more indepth and offers a more efficient method of doing the conversion. A working example of the solution is as follows (code is from the article above):

<apex:page controller="pdfpageController">
    <script>
        var base64String = "{!pdfData}";

        const byteCharacters = atob(base64String);

        const byteNumbers = new Array(byteCharacters.length);
        for (let i = 0; i < byteCharacters.length; i++) {
            byteNumbers[i] = byteCharacters.charCodeAt(i);
        }    

        const byteArray = new Uint8Array(byteNumbers);

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

        const blobUrl = URL.createObjectURL(blob);
        window.location = blobUrl;
    </script>
</apex:page>

I have a pdfData getter method in my controller that returns a (Base64) String.

Although this solution works, if you open the Visualforce page inside a sub tab (inside a console app) the page will not load because setting window.location is blocked in lightning. Instead, we need to create an iframe and set the source of it to our blobUrl.

<apex:page controller="pdfpageController">
    <iframe id="pdf"/>
    <script>
        var base64String = "{!pdfData}";

        const byteCharacters = atob(base64String);

        const byteNumbers = new Array(byteCharacters.length);
        for (let i = 0; i < byteCharacters.length; i++) {
            byteNumbers[i] = byteCharacters.charCodeAt(i);
        }    

        const byteArray = new Uint8Array(byteNumbers);

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

        const blobUrl = URL.createObjectURL(blob);

        document.getElementById('pdf').setAttribute('src', blobUrl);
    </script>
</apex:page>

This method is slightly better than setting the iframe source directly to the Base64 String since some browsers (like Chrome) have limits on the length an html element can be and if our Base64 String is over a certain length (2mb for Chrome), it won't be rendered. This should support rendering PDFs up to 6mb as that is the Apex variable size limit.

| improve this answer | |
-2

As an option you can convert your blob to string and then display it that way.

public String BlobText{get{return pdfBlobData.Tostring();}}

<apex:page renderAs="pdf"> {!BlobText} </apex:page>

| improve this answer | |
  • This gives ` common.apex.runtime.impl.ExecutionException: BLOB is not a valid UTF-8 string ` exception. I had tried this before. – NoNicknameSFDC Apr 29 '15 at 7:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.