3

I've written up a process to send Email's with PDF attachments through Visualforce Email templates and Visualforce Components. Within the Visual Force component, it escapes and renders out a Rich Text Field:

<apex:outputText value="{!email_header}" escape="false" />

As I understand it, the image is hosted on my Salesforce platform and can only be accessed through my own platform/logging in. But at the moment on the generated PDF it is blank. Through my own testing when I use an actual external image (http://whatever.com/something.jpg) it shows a "broken image icon".

My problem is that when I test and merge fields for this VF template it works perfectly fine (the image is present), but when I send the email via @future method it no longer works (the image is blank, the PDF still gets generated and sent) so I assume it's getting a permission denied error at some stage.


Apex to send the email:

    @future
global static void sendEmail(Id invoice_id){
    //Lots of code generating the below variables, cut out for readability
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

    mail.setSenderDisplayName(associate.Name);
    mail.setTargetObjectId(contact[0].Id);
    mail.setWhatId(invoice_id);
    mail.setTemplateId(et.Id);
    mail.setReplyTo(associate.Email__c);


    Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
  }

Visualforce Email Template:

<messaging:emailTemplate recipientType="Contact"
    relatedToType="Invoice__c"
    subject="Tax Invoice"
    replyTo="null@null.com.au">

    <messaging:htmlEmailBody >
       <html><body><p>Dear {!recipient.name},</p><p>Attached is a tax invoice .</p></body></html>
    </messaging:htmlEmailBody>

    <messaging:attachment renderAs="pdf" filename="Invoice_{!relatedTo.Name}.pdf">
        <c:Invoice_PDF_HTML_Content invoice_id="{!relatedTo.Id}" /><!-- Component generating PDF HTML -->
    </messaging:attachment>
</messaging:emailTemplate>
1

When you use an external image with PDF rendering you need to add the URL to the list of authorised end points in Remote Site Settings under setup. With a regular page your browser would be making the request, but with the PDF renderer it's being done server side.

That doesn't help with the image stored in Salesforce, but if hosting it externally is workable I'd go with that. As for the image stored in Salesforce I can't really think of a reason for it to fail, does it reserve the space for the image or is it just not in the flow at all?

  • It appears blank, but I'll add a border around the image to confirm / some text surrounding the image to test, I'll reply again when I can confirm. – Mattisdada Nov 6 '13 at 5:53
  • 100% blank, not even whitespace/margin/padding around the area where the image should be. It would appear that adding an external images site into Remote Sites does get around the external image issue, but I'm still very curious into why the Salesforce image is breaking :/ (read, it is working with an External image now :) ) – Mattisdada Nov 6 '13 at 5:56
  • Yeah the internal thing is confusing. Maybe try adding all the salesforce instances to remote site settings just to see if it changes anything? Or could it be an HTTP/HTTPS mismatch? – Matt Lacey Nov 6 '13 at 22:41
  • That's a good idea, I'll try it out now and I'll report back. Just to note, trying this on a Sandbox environment – Mattisdada Nov 6 '13 at 22:45
  • 1
    Yeah that is quite a bit of a last ditched effort, I might try it, but uploading to a remote location works for now, I would prefer "pure salesforce" method. I might be packaging this in the future and I would try more avenues of success after that, but for now, it works. It's just a little wonky... I might even write up a blog post about the "creating a PDF from a Trigger" journey, will definitely attribute you for your help LaceySnr, it has been invaluable – Mattisdada Nov 7 '13 at 0:07

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.