0

Is there a way to load a visual force page in apex controller without viewing the page.

The scenario is this I have a visualforcepage with apex:chart embedded. This page will save the chart as an attachment on salesforce record as image.

I want this page to reload every month to create an attachment image to the record

3 Answers 3

1

Basically, you need to scrap this idea. The charts are rendered in JavaScript, so unless you plan on writing a browser in Apex code, it's just not going to happen. You could try using Google's Chart Images, but they may choose to shut it down any day (it's been deprecated for 5 years now).

Or, find an alternative service that can do the work, either for free with watermarks or nominal monthly/annual charges; there's a lot of choices out there at an apparently reasonable price.

Alternatively, you could use open source like Image Magick and write a frontend for it, host it on heroku or AWS EB for a few cents/dollars a month. Basically, you'll need to make a callout to generate the charts from any of the above options.

Finally, maybe you could just create SVG images directly in Apex code. While I find that SVG is not the most human-friendly thing to do, once generated, you could store these files as attachments, and when they open in modern browsers, you'll have your chart image rendered.

0

Yes, and the tags that you included on your question actually pretty succinctly answers it. However, I don't think it'll be suitable for your purposes.

You can use Page.<visualforce page name here> in Apex to generate the PageReference, set the appropriate url parameters using something like getParameters().put('id', <your record id>), and then the getContent() method of the pagereference to cause Salesforce to render your page (including your chart).

The gotchas here are:

  • getContent() is treated as a callout, meaning you can't perform any DML (or DML-like things such as enqueuing a Queueable class) prior to calling this method
  • You're going to get HTML as a return value. Digging through the HTML for your chart is going to be a chore (regex isn't really a good tool for that job)
  • <apex:chart> probably doesn't render as an image

That last one is (probably) the dealbreaker. I'd imagine that the <apex:chart> tag renders HTML with some CSS styling to make it presentable. I'm not in a position to dig further into that right now, though. Suffice it to say, I haven't heard of anyone converting HTML into a .gif (or other image format) without taking a screenshot.

I'm also not sure how well the general approach would work if you're trying to render a page from within the controller (or extension) for that page.

3
  • Thanks Derek. Currently I am able to generate those image chart and save it as an attachment to the record.
    – hpmacugay
    Commented Jan 16, 2019 at 4:04
  • I already tried getcontent but it does not renders the chart as you said. What I want to do is, since i am able to generate the charts as image I want it to do to all the records since i need this page to render the chart as image Is it possible to execute this custom page without opening it.
    – hpmacugay
    Commented Jan 16, 2019 at 4:08
  • FYI, apex:chart is rendered by JavaScript so it can do the pretty animations and whatnot.
    – sfdcfox
    Commented Jan 16, 2019 at 6:03
0

Salesforce does not support saving page as an image. I would like to suggest to save the page as pdf. Also note Attachments are no longer encouraged to use, better to use Files instead. Below code may help.

Visualforce: must specify render as PDF as below.

apex:page controller="myController" showHeader="false" renderAs="pdf"

Apex:

PageReference vfpage = Page.myVFPage;
Blob body;
if (!test.isRunningTest()){
    body = vfpage.getContent();
} else {
    body = Blob.valueOf('Test mode.');

String fileName = 'mypdf - ' + String.valueOf(system.today()) + '.pdf';
ContentVersion cv =new ContentVersion(Title = fileName); 
cv.VersionData = body;
cv.PathOnClient='/' + fileName ;
insert cv;

cv = [select ContentDocumentId from ContentVersion where id=:cv.Id];
insert new ContentDocumentLink(ContentDocumentId = cv.ContentDocumentId, ShareType = 'V', LinkedEntityId = dNId);
1
  • 1
    Unfortunately, this won't work, because the charts are rendered by JavaScript.
    – sfdcfox
    Commented Jan 16, 2019 at 6:03

You must log in to answer this question.

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