Generating documents in Salesforce with Visualforce Pages

We take you under the hood of our document design and generation tool, Weaver

Aug 5, 2019 · 5 min read

Here at Appitek we’ve just publicly launched Weaver, our first Salesforce AppExchange app —and it wasn’t without it’s challenges.

There are plenty of ways to generate documents on Salesforce, whether with standard functionality, custom code, or AppExchange solutions, but just how to you go about building you own? In this article we’re going to show you how you can get started.

At the core of creating documents are our trusty Visualforce (VF) pages. As the development community turns more and more to Lightning and Lightning Components it’s easy to forget about what now feels like an antiquated platform, but VF still has some important uses- including document generation.

Simply by adding the “renderAs” attribute, suddenly your VF page is rendered as a PDF!

Your first PDF! It really is that easy.

One thing you might notice straight away is custom CSS you write inside the VF page is ignored instead of being applied but don’t worry you’re not going crazy, it’s just one of the many quirks of PDF rendering!

Where’s my styling gone?

You will always need to put your CSS either inline, or load in a CSS stylesheet via an <apex:stylesheet/> or your styles will get ignored. Think of it like having to pre-load your styles before the page loads.

That’s much better!

In Weaver we take this even further, by setting the style sheet values as CSS files loaded from Salesforce, as well as dynamically generating extra CSS in Apex to apply before the page loads! (HINT: Make sure any files or content you use are publicly accessible!)

The next thing you might notice is that certain properties, such as border-radius, opacity, or even custom fonts don’t work. This is because Salesforce’s rendering engine is an older version of Flying Saucer, meaning you can only use CSS2.1 properties.

Some of the more basic features you will want to add into your documents are custom margin sizes, header / footer sections, and page numbers. These are all controlled by CSS, but specifically “Page” CSS, a special subsection dedicated to print related rendering, which includes PDFs.

Control page size, margins, footers, page numbers, and more, all with CSS

By adding some “Page” CSS properties to our VF page, you can not only create these features, but also do stuff like:

  • page sizes (size attribute)
  • table of contents (content & target-counter attributes)
  • cover pages (:first modifier)

So we have our VF page, and it’s looking great, but now we want to add in Salesforce data! Luckily this is also built in and ready for you, using standard controllers and Salesforce merge fields.

In this example, we’ll use the “Account” standard controller, meaning we can reference our Account’s system fields with the merge field syntax — “{!record.FieldName}”.

To see this in action, all we need to do is preview our VF page, and pass in a record Id through the URL, e.g. “/apex/Example?id=myRecordId” ( Don’t forget to extend your standard controllers to get other fields!)

Dynamic data straight into our PDFs without any extra code

As this URL can be accessed for any record, we could then create buttons for your users that link to this page, dynamically passing in the record Id for the URL, and you now have a PDF generating button on every record!

Using the URL is great for manually generating documents on demand, but what about if you want to automate these documents? Not only does Salesforce save you a bunch of work by creating the PDF for you, but it also gives you an easy way to access VF pages dynamically.

In Apex we can create a virtual version of our VF page, apply the target record Id for our dynamic data, then virtually render the final PDF.

Sound complicated? It’s far easier than you’d think, and achievable in only 3 lines of code!

Once you have your PDF “Blob” you can save it wherever you like in Salesforce as a file, document, or an attachment to the same record! You could call this function from a Flow, Process Builder, or even a Trigger, meaning you can automate the process.

What else can we do with the renderAs tag? Well you can actually create a few other types of documents automatically. (HINT: If you’re using one of these formats with Apex, you’ll need to use getContentAsBlob() instead of PDF!)

Word (.doc)

Excel (.xls)

Weaver outputting a Word document, using the renderAs tag

(P.S. Salesforce please bring back advanced_pdf! ❤)

We hope you found this interesting and try out creating documents on Salesforce for yourself!

If you want to see how far we took this document design and generation on-platform, you can install a free 30-day trial of Weaver today with zero commitment.

At Appitek, our aim is to help make your job easier, by creating simple but effective Salesforce applications that make you more efficient at what you do.

Appitek is a registered Salesforce ISV partner.
Salesforce and Salesforce Lightning are registered trademarks of


We build innovative solutions for business, using the best of modern capabilities and technologies. Behind all that? The power of Salesforce.


Written by


Multidisciplinary full stack developer, with a history in product & digital design. CTO at Appitek Ltd.



We build innovative solutions for business, using the best of modern capabilities and technologies. Behind all that? The power of Salesforce.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade