Print Anything To Google Docs

Using Print Anything and Google Docs to create PDFs from Force.com data

Introduction

Adobe Portable Document Format (PDF) is often used to create and print documents with a professional appearance. Many Salesforce and Force.com users would like to be able to create PDF files from Force.com data, but that capability is not built into the Force.com platform (yet). However, Google Docs allow you to save any document as a PDF. I recently pulled together these two platforms, along with the Print Anything application on the salesforce AppExchange, to create a solution that delivers a PDF from Force.com data. I was able to accomplish this without very much work, and you can build on my modifications with the code that is included in this post.

Combining Great Features

Two features, one from Google and one from Salesforce, made the process flow simple. The first feature is the Google Docs upload email address that all Google Docs users have. You can find it by logging into Google Docs and clicking on this LINK. The link provides a simple but elegant method of loading an HTML document into Google Docs by just sending an email. The feature makes delivery to Google Docs a snap.

The second feature is the the cool new Salesforce feature to send an Email directly from an SControl. Before you can use this feature to send a document to Google Docs, you will have to first create a custom s-control to use Print Anything to create an HTML document with the queries and a template provided by the application. Once this step is completed, the s-control can simply send the HTML document to a Google Docs user, which is then stored in Google Docs in a moment or two. Once the document is in Google Docs, the user can save the document into PDF format.

Get Started Building

The first step toward implementing this solution is to install the Print Anything application from the AppExchange, and learn how to build templates with this app. When the Print Anything application is up and running, you can modify its code. Since Print Anything is a managed app, you must make a copy of the Print Anything driver s-control that you will change. You simply open a new s-control and paste in the source code from the original. Give the new s-control a distinctive name, such as Print Anything Driver2, to avoid confusion.

The next step is to add a new field to the User object to hold the Google Docs upload email address. This field should be a text field, with a length of 128 and a descriptive name, such as Google_Docs_Upload_Email . We will use the address in this field later to provide an email address to the s-control for the sendEmail() API call.

Editing Print Anything Source Code

The next step is to add two new parameters, modify one function and add one new function to the new version of the Print Anything driver.

Near the top of the file, add this

var exportGoogle = false;

Lower down in the setup() function, add this code to set the exportGoogle variable

exportGoogle = window.location.href.indexOf("google") != -1;

You will also use a parameter "doctitle" to specify a title when the document is sent to Google, but you will specify this title in the call to the modified Print Anything driver, which is included below.

You next locate the function mergeContent() and add the following code to the very end, which will call the new function you will create:

if (exportGoogle) { 
  emailContent();
}

Send Email from Scontrol

The final task of this step is to add the new function, which will create the actual call to the sendEmail() API function. The function that I created is listed below, although you may wish to implement it differently to suit your specific purposes.

 function emailContent( ) {

     // need the location to email to, get that from the user field
     // Google_Docs_Upload_Email__c
     if ( "{!User.Google_Docs_Upload_Email__c}" == "" ) {
      prtanyDebug("No Google Docs Email specified in user record","debug");
      return;
     }

     // prepare an outgoing email
     var singleRequest = new sforce.SingleEmailMessage();
     var subject = mergeData["Parameter.doctitle"];
     subject = subject.replace(/\+/g,' ');

     singleRequest.subject = (subject?subject:'untitled document from: ' +
       mergeData["UserInfo.Email"]);
     singleRequest.plainTextBody = "none";
     singleRequest.htmlBody = document.getElementById("divContent").innerHTML;
     singleRequest.toAddresses = ["{!User.Google_Docs_Upload_Email__c}"];
     singleRequest.useSignature = false;
     var sendMailRes = sforce.connection.sendEmail([singleRequest]);
     prtanyDebug("Google Docs Email sent to: {!User.Google_Docs_Upload_Email__c},
      titled:"+subject,"debug");

 }

Modify Custom Link

The last step is to add code to call the modified Print Anything driver. I called the driver with the following URL - you will probably need to change the package ID to match the one you require. The google=1 indicates a call to the sendEmail() function in the modified driver and the doctitle is what appears as the title in the Google Docs document after it arrives.

 {!URLFOR($SControl.Print_Anything_Driver2 ,  
    Account.Id, [packageId="contacts" , google="1", debug="1", doctitle="Print Anything from Salesforce"]) }

Summary

With this small amount of code, you are now ready to run. If a user does not have a Google Docs email address specified, the function will simply return an error message to them. Once you fully test the new functionality, you will probably want to eliminate the parameter which turns on debugging (debug="1"). You can still print in the standard Print Anything way with the modified driver.

There are lots of ways to extend and enhance this idea. For instance, you could use existing data to build the title of the document. Hopefully, this simple example will give you a great starting point for not only creating PDF documents from Force.com data, but also for integrating data from the Force.com data services to Google Docs. Enjoy!

- Ron Hess, with Rick Greenwald