1

I have a Visualforce page that generates a PDF document (it contains renderAs="pdf"). If I use the URL of the page directly and supply some parameters, it works brilliantly. Embedded images, the Arial font, even a page break (done with CSS).

But: if I try to get this PDF using Pagereference ... getContent(), I always get a PDF with 2 blank pages. The number of bytes are correct, the font is correct, but the contents are blank.

I have tried a lot: set the font, the color, ... The method that calls getContent() is a synchronous method, I think that is important, because there are some constraints. Googling shows people with the same problem, but so far, no solution helps my particular situation.

The code of the page as it is per 2016-01-19:

<apex:page id="authorizationForm" language="!$CurrentPage.parameters.language}" showHeader="false" sidebar="false" standardStylesheets="false" applyBodyTag="false">
<head>
<style type="text/CSS">
  @page {
    size: A4;
    margin: 25mm;
  }
  body {
    font-family: 'Arial Unicode MS';
    font-size: 11px;
    color: black;
  }
</style>
</head>
<body>


Things with <apex:outputText> etc.

</body>
</html>
</apex:page>

The code that performs the getContent() as it is per 2016-01-19:

RestResponse res = RestContext.response;
PageReference authorizationForm = Page.AuthorizationForm;
res.addHeader('Content-Type', 'application/pdf');
Blob pdfBody = authorizationForm.getContentAsPdf();
res.statusCode = 200;
res.responseBody = pdfBody;
18
  • have you tried getContentAspdf() method? developer.salesforce.com/docs/atlas.en-us.apexcode.meta/…
    – Ratan Paul
    Dec 8, 2015 at 15:10
  • Hi Sander, can you clarify what you're trying to accomplish? Are you just trying to give users a way to download the correct PDF? In that case I think an apex:outputLink using URLFOR() should work for you.
    – Marty C.
    Dec 8, 2015 at 15:51
  • 1. Are the pages completely blank or it contains the static text but values from objects/controllers are not populating on the pdf? 2. Where are you calling the getContent from.. a controller or a trigger?
    – Aayush K
    Dec 8, 2015 at 16:53
  • @Ratan Yes, there is no difference between getContent and getContentAsPDF Dec 9, 2015 at 8:54
  • 1
    @SanderdeJong Have you tried Base64 encoding the response, as suggested in salesforce.stackexchange.com/questions/50371/…
    – joe
    Jan 19, 2016 at 16:49

2 Answers 2

1
+50

I'm a little confused by your updated question. I'm not sure what you're doing with the response object. Here's a little test that I just did which might give you some food for thought:

Visualforce:

<apex:page id="authorizationForm" language="!$CurrentPage.parameters.language}" showHeader="false" sidebar="false" standardStylesheets="false" applyBodyTag="false">
<html>
<head>
<style type="text/CSS">
  @page {
    size: A4;
    margin: 25mm;
  }
  body {
    font-family: 'Arial Unicode MS';
    font-size: 11px;
    color: black;
  }
</style>
</head>
<body>


Things with apex:outputText etc.

</body>
</html>
</apex:page>

Apex REST:

@RestResource(urlMapping='/TestPDF/') 
global class TestRestPDF 
{
    @HttpGet
    global static String getPdf()
    {
        Blob pdf = new PageReference('/apex/authorizationForm').getContentAsPDF();
        return EncodingUtil.base64Encode(pdf);
    }
}

The REST service basically returns a Base64 encoded String representing the PDF. You would then need to decode that in your client app to reconstruct the PDF. You could also generate the PDF directly from the response of the method, for example if you were to paste this in its entirety to your browser URL you'd get a PDF on screen:

data:application/pdf;base64,JVBERi0xLjQKJeLjz9MKMyAwIG9iaiA8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDE1NT4+c3RyZWFtCnicVY5NC4JAGITv8yveY122/VAXOwZ1CDoIL3SIDpHmB2laK/rzW5UOMZeHGZiZDjuGJBtr4hR7RoIOUkhjQxqg6ejDCkrSCZerpBQmIhtGVCO0Cz1nMpGQgWfzh0te4IzG90x659Pg5qBI+cUH1OwqCjRZEwsdENdYcVE2+YeG0hV0a7Nx++pd2zvORkeZu4s1V7+vCb6RsCysCmVuZHN0cmVhbQplbmRvYmoKMSAwIG9iajw8L0NvbnRlbnRzIDMgMCBSL1R5cGUvUGFnZS9SZXNvdXJjZXM8PC9Qcm9jU2V0IFsvUERGIC9UZXh0IC9JbWFnZUIgL0ltYWdlQyAvSW1hZ2VJXS9Gb250PDwvRjEgMiAwIFI+Pj4+L1BhcmVudCA0IDAgUi9NZWRpYUJveFswIDAgNjEyIDc5Ml0+PgplbmRvYmoKMiAwIG9iajw8L1N1YnR5cGUvVHlwZTEvVHlwZS9Gb250L0Jhc2VGb250L1RpbWVzLVJvbWFuL0VuY29kaW5nL1dpbkFuc2lFbmNvZGluZz4+CmVuZG9iago0IDAgb2JqPDwvS2lkc1sxIDAgUl0vVHlwZS9QYWdlcy9Db3VudCAxPj4KZW5kb2JqCjUgMCBvYmo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgNCAwIFI+PgplbmRvYmoKNiAwIG9iajw8L01vZERhdGUoRDoyMDE2MDExOTE1NDk0MFopL0NyZWF0aW9uRGF0ZShEOjIwMTYwMTE5MTU0OTQwWikvUHJvZHVjZXIoaVRleHQgMi4wLjggXChieSBsb3dhZ2llLmNvbVwpKT4+CmVuZG9iagp4cmVmCjAgNwowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAyMzcgMDAwMDAgbiAKMDAwMDAwMDM5MyAwMDAwMCBuIAowMDAwMDAwMDE1IDAwMDAwIG4gCjAwMDAwMDA0ODIgMDAwMDAgbiAKMDAwMDAwMDUzMiAwMDAwMCBuIAowMDAwMDAwNTc2IDAwMDAwIG4gCnRyYWlsZXIKPDwvSW5mbyA2IDAgUi9JRCBbPGEzODZjZTliMzUzZDFhMGYwMTQwOWQ1YzBiNGI0MDlhPjw3YzkzZWNhOTRjNTBmM2FlN2E1NzU0NWUzMDgwZWFjZT5dL1Jvb3QgNSAwIFIvU2l6ZSA3Pj4Kc3RhcnR4cmVmCjY5NQolJUVPRgo=

What is your client application? i.e. the application calling your REST service?

This also appears to return correctly:

global class TestRestPDF 
{
    @HttpGet
    global static void getPdf()
    {
        Blob pdf = new PageReference('/apex/authorizationForm').getContentAsPDF();

        RestContext.response.addHeader('Content-Type', 'application/pdf');
        RestContext.response.responseBody = pdf;
    }
}

Though, I can only see the RAW response, it may well be worth converting to Base64 first, e.g.:

RestContext.response.responseBody = Blob.valueOf(EncodingUtil.base64Encode(pdf));
1
  • Thanks, the crucial part is doing Blob.valueOf(EncodingUtil.base64Encode(pdf)) instead of just pdf. Kudos also to joe, whose comment pointed to the same solution. Jan 20, 2016 at 13:50
0

I'm admittedly not an expert in PDF content delivery, but your requirement for not giving users a Salesforce URL and instead displaying the PDF in read-only format lends itself to one of two options (I think):

  1. Use UrlRewriter to obscure the Salesforce URL, and perhaps create a custom object (e.g., PdfDelivery__c) to track the parameters of each PDF generation request.
  2. Use a secure container like what Salesforce uses for its content deliveries.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .