Generating SSRS Report and adding it as an attachment to a record using JavaScript

Recently I had a requirement to generate a report and add it as a Attachment to a record on click of a button.

In the following code just replace ‘reportname’,’reportGuid’, ‘strParameterXML’ and ‘CRM_ReportParameterIfAny’ with the actual values and bind AttachReport Method to ribbon button commannd.

var base64 = null;

function AttachReport() {
    createAttachment();
}

function createAttachment() {
    var params = getReportingSession();
    if (msieversion() >= 1) {
        encodePdf_IEOnly(params);
    } else {
        encodePdf(params);
    }
}

function getReportingSession() {
    var reportName = "My Report.rdl"; //set this to the report you are trying to download
    var reportGuid = "000000-00000-0000-0000-000000000000"; //set this to the guid of the report you are trying to download          
    var selectedIds = Xrm.Page.data.entity.getId();
    var pth = Xrm.Page.context.getClientUrl() + "/CRMReports/rsviewer/reportviewer.aspx";
    var retrieveEntityReq = new XMLHttpRequest();

    var strParameterXML = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'><entity name='enitity_name'><all-attributes/><filter type='and'><condition attribute='recordid' operator='eq' value='" + selectedIds + "' /> </filter></entity></fetch>";

    retrieveEntityReq.open("POST", pth, false);

    retrieveEntityReq.setRequestHeader("Accept", "*/*");

    retrieveEntityReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

    retrieveEntityReq.send("id=%7B" + reportGuid + "%7D&uniquename=" + Xrm.Page.context.getOrgUniqueName() + "&iscustomreport=true&reportnameonsrs=&reportName=" + reportName + "&isScheduledReport=false&p:CRM_ReportParameterIfAny=" + strParameterXML);
    var x = retrieveEntityReq.responseText.lastIndexOf("ReportSession=");
    var y = retrieveEntityReq.responseText.lastIndexOf("ControlID=");
    // alert("x" + x + "y" + y);
    var ret = new Array();

    ret[0] = retrieveEntityReq.responseText.substr(x + 14, 24);
    ret[1] = retrieveEntityReq.responseText.substr(x + 10, 32);
    return ret;
}

function createEntity(ent, entName, upd) {
    var jsonEntity = JSON.stringify(ent);
    var createEntityReq = new XMLHttpRequest();
    var ODataPath = Xrm.Page.context.getClientUrl() + "/XRMServices/2011/OrganizationData.svc";
    createEntityReq.open("POST", ODataPath + "/" + entName + "Set" + upd, false);
    createEntityReq.setRequestHeader("Accept", "application/json");
    createEntityReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    createEntityReq.send(jsonEntity);
    var newEntity = JSON.parse(createEntityReq.responseText).d;

    return newEntity;
}

var StringMaker = function () {
    this.parts = [];
    this.length = 0;
    this.append = function (s) {
        this.parts.push(s);
        this.length += s.length;
    }
    this.prepend = function (s) {
        this.parts.unshift(s);
        this.length += s.length;
    }
    this.toString = function () {
        return this.parts.join('');
    }
}

var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

function encode64(input) {
    var output = new StringMaker();
    var chr1, chr2, chr3;
    var enc1, enc2, enc3, enc4;
    var i = 0;
    while (i < input.length) {
        chr1 = input[i++];
        chr2 = input[i++];
        chr3 = input[i++];
        enc1 = chr1 >> 2;
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
        enc4 = chr3 & 63;
        if (isNaN(chr2)) {
            enc3 = enc4 = 64;
        } else if (isNaN(chr3)) {
            enc4 = 64;
        }
        output.append(keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4));
    }
    return output.toString();
}

function encodePdf_IEOnly(params) {
    var bdy = new Array();
    var retrieveEntityReq = new XMLHttpRequest();
    var pth = Xrm.Page.context.getClientUrl() + "/Reserved.ReportViewerWebControl.axd?ReportSession=" + params[0] + "&Culture=1033&CultureOverrides=True&UICulture=1033&UICultureOverrides=True&ReportStack=1&ControlID=" + params[1] + "&OpType=Export&FileName=Public&ContentDisposition=OnlyHtmlInline&Format=PDF";
    retrieveEntityReq.open("GET", pth, false);
    retrieveEntityReq.setRequestHeader("Accept", "*/*");
    retrieveEntityReq.send();
    bdy = new VBArray(retrieveEntityReq.responseBody).toArray(); // minimum IE9 required
    createNotesAttachment(encode64(bdy));
}

function encodePdf(params) {
    var xhr = new XMLHttpRequest();
    var pth = Xrm.Page.context.getClientUrl() + "/Reserved.ReportViewerWebControl.axd?ReportSession=" + params[0] + "&Culture=1033&CultureOverrides=True&UICulture=1033&UICultureOverrides=True&ReportStack=1&ControlID=" + params[1] + "&OpType=Export&FileName=Public&ContentDisposition=OnlyHtmlInline&Format=PDF";
    xhr.open('GET', pth, true);
    xhr.responseType = 'arraybuffer';
    xhr.onload = function (e) {
        if (this.status == 200) {
            var uInt8Array = new Uint8Array(this.response);
            base64 = encode64(uInt8Array);
            createNotesAttachment(base64);
        }
    };
    xhr.send();
}

function msieversion() {
    var ua = window.navigator.userAgent;
    var msie = ua.indexOf("MSIE ");
    if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./))      // If Internet Explorer, return version number
        return parseInt(ua.substring(msie + 5, ua.indexOf(".", msie)));
    else                 // If another browser, return 0
        return 0;
}

function createNotesAttachment(base64data) {
    var post = Object();
    post.DocumentBody = base64data;
    post.Subject = " Test";
    post.FileName = "Test.pdf";
    post.MimeType = "application/pdf";
    post.ObjectId = Object();
    post.ObjectId.LogicalName = Xrm.Page.data.entity.getEntityName();
    post.ObjectId.Id = Xrm.Page.data.entity.getId();
    createEntity(post, "Annotation", "");
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s