Idea: Page to Print, Page to PDF, Page to Email, Page to Content actions

One more question for the docraptor experts… How do I get local css on my page? I use a skuid custom theme, and I opened the static resource and see all the files in the zip. I opened the skuidtheme file and copied all the text into a new css resource on my document skuid page, and then applied the css to my wrapper that is the content for my document. It didn’t work. :frowning: Am I close, or what else can I do to “send css to docraptor?”

Hi Chandra,

You can inject the css from a different location with an ‘Inline’ Javascript snippet like this:

(function(skuid){ var $ = skuid.$; $(document.body).one('pageload',function(){ //Change the static resource to the org's static resource location TODO: Dynamically set this $.when($.get("/resource/###############/<THEME_NAME>/skuidtheme.css")) .done(function(response) { // Create style tag to inject var style = $('<style />'); style.append(response); //inject it into the page style.appendTo($('#pdf-export')); }); }); })(skuid);

Henry - this worked perfectly.  Thank so much!  Please tell me you are going to Dreamforce or something, and I will buy you a beer or 12.  

Last question (haha)… I have a record detail page and want my user to click the “print doc” button.  The document layout (in my pdf wrapper) is not the same as the detail page.  I don’t want the user to see the wrapper/pdf but if I hide it with conditional rendering, then the pdf ends up blank.  What do you do with your wrapper/pdf on your detail page so it loads on your page, but the users don’t see it?

Chandra if I find myself in San Fransisco for Dreamforce I’ll certainly take you up on the beer offering!

As for hiding your print button, you can either put the button outside of the wrapper of id ‘pdf-export’ or do the following.

  1. Create a UI only checkbox called ‘hideprintbutton’ or something like that.
  2. Put a render condition on the button on the ‘hideprintbutton’ being true.
  3. Then perform the following ‘multiple actions’ on the button click:

We currently perform the latter option and it works very nicely. Hope this does the trick for you too!

Worked again!!  :)))

New problem - page loading in the skuidtheme.css has caused this portion of the Theme to apply to my whole page, so that means my pages are missing the skuidicon.css portion of the Theme.  So no icons on my page.  :(

I moved this problem to a more detail new thread here:
https://community.skuid.com/t/embed-css-into-wrapper-component-page?rfm=1&topic_submi…

#Mansourisagenius

so, yeah #Mansourisagenius. DocRaptor is pretty amazing too. I’ve been implementing this today, and their tech support said that the above snippet I was using was old, that they’ve got a JS library now, so it’s better to reference that.

So, step 1, create an external snippet with this url: http://docraptor.com/docraptor-1.0.0.js
(or download that and upload as a static resource)

step 2, create an new snippet, remove all the standard code skuid adds in, then use this:

function downloadPDF() { DocRaptor.createAndDownloadDoc("YOUR_API_KEY_HERE", { test: true, document_type: 'pdf', name: 'test.pdf', document_content: document.querySelector('#pdf-export').innerHTML, strict: 'none', javascript: 'true', prince_options: { // if you want relative links to work baseurl: 'YOUR_SALESFORCE_BASE_URL' } }); } downloadPDF();

Everything else about the inlineJS to append your them to the wrapper is key, as is naming your wrapper with a unique id “pdf-export”.

also, in the inlineJS to append the theme css, you can add extra styles. for example, I had trouble adding the docrapter-specific @page selector to my theme (that controls landscape vs. portrait, and other page sizes), so I added it directly in the inlineJS, as such:

 var style2 = $('<style> @page { size : US-Legal landscape } </style>');
                style2.appendTo($('#pdf-export'));

Great stuff!  We have several doc raptor docs incorporated into our skuid processes.  I did a new one this morning using the new DocRaptor library.  Worked great!

Thanks for the update on this!

You’re welcome Chandra! Thank YOU for all the formatting tips you shared. Any chance you could share the apex code you used to grab the document that DocRaptor created and attach it back to a record in Salesforce? Did you have to run the async call to DocRaptor and get the callback_url?

ok, here we go. First, the apex class which is generic and will attach to any record id that you pass it. So we use this class for lots of objects.
/*—=============================================================================
— Program Name : AFLattachAsPDF

— Program Description : This APEX class attaches pdf documents from given url
— to the record specified.

— Date Written : 25-Jun-2016
—=============================================================================*/
global class AFLattachAsPDF{
webservice static void attachAsPDF(string downloadURL, ID theId, string theName){
Http h = new Http();
HttpRequest req = new HttpRequest();
string theURL = downloadURL;
req.setEndpoint(theURL);
req.setMethod(‘GET’);
//another example would be ‘image/jpeg’
req.setHeader(‘Content-Type’, ‘application/pdf’);
req.setCompressed(true);
req.setTimeout(60000);
HttpResponse res = null;
res = h.send(req);
//next three lines for dealing with error situations
//string responseValue = ‘’;
//responseValue = res.getBody();
//system.debug('Response Body for File: ’ + responseValue);
blob thePDF = res.getBodyAsBlob();

    Attachment attachment = new Attachment();
    attachment.Body = thePDF;
    attachment.Name = theName + '.pdf';
    attachment.ContentType = 'application/pdf';
    attachment.ParentId = theId;
  insert attachment;

}
}

Then, the Skuid snippet that runs. It has the DocRaptor call, brings in our special custom Skuid theme that we use just for documents, polls docraptor checking for completion of the pdf, creates a document name and passes all the info to the apex class (the url exposed by DocRaptor, the Id to attach the pdf to and the document name you want.)

This example is from our Quote page where the user clicks a button which calls the document skuid page in a pop up window, and this snippet runs on page load. Once the document is done, the window closes and poof the pdf is attached to the quote.

var params = arguments[0],
$ = skuid.$;

var quoteModel = skuid.model.getModel(‘quote’);
var quoteRow = quoteModel.getFirstRow();
var quoteNum = quoteModel.getFieldValue(quoteRow,‘Name’);
var quoteRev = quoteModel.getFieldValue(quoteRow, ‘Quote_Revision__c’);
var docName = quoteNum + ‘R’ + quoteRev;
var docURL;

// pull in the Skuid theme to apply to the page
$.get(“/resource/yourthemepath/yourthemename/skuidtheme.css”,function(response){
// Create style tag to inject
var style = $(‘’);
style.append(response);
// apply a custom border to a dynamically created table
style.append(‘table, th, td {border: 1px solid black;border-collapse: collapse;padding: 1px;text-align: left;}thead {background-color: #000000;color: #FFFFFF;}’);

//inject it into the page
style.appendTo($(‘#pdf-export’));

function checkDocumentStatus(id){
$(‘.status span’).html(‘Polling…’);
$.ajax({
type: ‘GET’,
url: ‘https://docraptor.com/status/’+id,
dataType: ‘JSON’,
beforeSend: function(req) {
req.setRequestHeader(‘Authorization’, ‘Basic ’ + btoa(‘YOUR ACCESS CODE’));
},
success: function(data){
if(data.status == ‘queued’ || data.status == “working”){
// wait 1 second, check again
setTimeout(checkDocumentStatus, 1000, id);
}else if(data.status == ‘completed’){
$(’.status span’).html(‘Completed’);
$(‘.url span’).html(data.download_url);
docURL = data.download_url;
try{
var attName = quoteModel.getFieldValue(quoteRow, ‘Name’) + ‘R’ + quoteModel.getFieldValue(quoteRow, ‘Quote_Revision__c’);
var result = sforce.apex.execute(‘AFLattachAsPDF’, ‘attachAsPDF’, {downloadURL: docURL, theId: quoteModel.getFieldValue(quoteRow, ‘Id’), theName: attName});
skuid.model.updateData(
[quoteModel]
,function(){

quoteModel.save();
});

window.close();

}catch(e){
alert(e);
}
//window.prompt(‘Download URL’, data.download_url);
}else{
$(‘.status span’).html(data.status);
}
}
});
}


function makeDocument(content){
$(‘.status span’).html(‘Requested’);

content = content || ‘’;

$.ajax({
type: ‘POST’,
url: ‘https://docraptor.com/docs’,
data: JSON.stringify({
‘type’: ‘pdf’,
‘document_content’: content,
‘name’: docName,
//‘test’: true,
‘async’: true,
//‘pipeline’: 6,
‘prince_options’: {
‘media’: ‘print’,
‘owner_password’: quoteNum,
‘disallow_modify’: true,
‘encrypt’: true,
‘key_bits’: ‘128’
}
}),
contentType: ‘application/json’,
dataType: ‘json’,
beforeSend: function(req) {
req.setRequestHeader(‘Authorization’, ‘Basic ’ + btoa(‘YOUR ACCESS CODE’));
},
// upon success of the ajax request
success: function(data){
$(’.status span’).html(‘request made’);
checkDocumentStatus(data.status_id);
}
});
}


//----------------------------------------------------------------------------------------------------

// setup the string represeting the html we want to submit
var content = $(‘#pdf-export’).html();

makeDocument(content);

});

Wow! Awesome… thanks for sharing!

Hi everyone, I’m a member of the DocRaptor support team and just stumbled across this. Thanks for sharing this info, Henry. If anyone needs assistance with DocRaptor, please don’t hesitate to reply to me here or contact support@docraptor.com. Thanks!

Hi James, thanks for finding us. I was just reading a bit about Domains on the DocRaptor site. Seems like this could make implementation within skuid even easier, just create a link on a skuid page with the right query parameters. Also keeps it more secure because you don’t have to put your api key into a js snippet. 

However, i’ve been unable to get this to work with some minor tests. I was wondering if, given some of the examples people have shown above, you could give us an expanded example of how to use the domains feature?

I’ve already gone through the documentation here: https://docraptor.com/documentation/api#referrer_based 

Jack - we saw this as well, although our stuff is on auto-pilot so we did not go back and update it.  The only change we made since my old posts is to have the apex insert the returned pdf as a File instead of an attachment, since we have now moved our org off of notes and attachments.

Jack, could you send support@docraptor.com your code and what URL the code is being tested on? 

The examples included on the documentation page already are as advanced as the code gets, from a code perspective. It’s mainly a matter of troubleshooting any domain vs referrer problems (not all websites all the sending of referrers, for example).

I wanted to follow up on this topic as I now have a much better understanding of how Skuid works. I don’t think DocRaptor’s Referrer Based system will work for Skuid users because it requires that the page to be converted by public (not secured behind a login and password). I’m working on better documenting the process for adding DocRaptor to your Skuid app and hope to have a streamlined guide for that shortly (mainly drawn from Chandra’s code above).

A quick question… I have the docraptor solution working but we have attachments (photos) that we would like to render in the document. They appear on the screen but not the pdf?

Anyone else sorted this one out? 

Hi James… We have the docraptor solution working to generate a pdf for a report but we have files attached (photos) that we would like to render in the document. They appear on the screen but not the pdf? Any assistance would be greatly appreciated

Hi @Henry_Goddard, thank you so much for providing the solution. I have used this exact code but getting this error on the console:

I have added the API key from docraptor in the user credentials. I have also added the origin site in the CORS allowed origin list but it is still not working. Any guidance to resolve this would be of great help.

@Rob_Hatch @Skuidward_Tentacles @Chandra_V @Jack_Sanford @James_Paden