Could you please help me with generating a Word document in ServiceNow?

KanishkaS814962
Tera Contributor

Could you please help me with generating a Word document in ServiceNow? I am looking for a solution similar to how PDF documents are generated. Has anyone implemented Word document generation for any record in ServiceNow? If so, I would appreciate guidance on how to configure it.

I want to create a UI Action in Workspace where a user can select a record and click a button to generate a Word document. We can generate PDFs, but I am not sure how to do the same for Word documents. Could you please provide the steps or a working solution?

1 ACCEPTED SOLUTION

indersinghp
Tera Expert

Hi @KanishkaS814962 ,

You can achieve this requirement by implementing a UI Action. Specifically, you will need to configure a client-side UI Action together with a client-callable Script Include. Both components work in coordination to generate the Word document. The implementation details and code samples are provided below:

 

Here is the UI Action script:-

 

function onClick() {

    var ids = g_list.getChecked();   // returns comma-separated sys_ids

    if (!ids) {
        alert("Please select at least one record.");
        return;
    }

    // Call script include
    var ga = new GlideAjax('BGHDownloadUtils');
    ga.addParam('sysparm_name', 'downloadDoc');
    ga.addParam('sysparm_ids', ids);

    ga.getXML(function(response) {

        var attId = response.responseXML.documentElement.getAttribute("answer");

        if (!attId) {
            alert("Failed to generate document.");
            return;
        }

        // Start download
        window.location = "/sys_attachment.do?sys_id=" + attId;
    });

}
 
Here is the Script Include Script:-
 

var BGHDownloadUtils = Class.create();
BGHDownloadUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {

downloadDoc: function() {

var ids = this.getParameter('sysparm_ids');
if (!ids)
return "";

var idList = ids.split(',');

// This will hold the combined HTML
var mergedHTML = "";

// Loop through each selected record
for (var i = 0; i < idList.length; i++) {

var rec = new GlideRecord('incident'); // Change table if required
if (!rec.get(idList[i]))
continue;

// Build HTML content manually (NO TEMPLATE USED)
var html = "";

html += "<h2>Incident Details</h2>";
html += "<p><b>Number:</b> " + rec.getValue("number") + "</p>";
html += "<p><b>Short Description:</b> " + rec.getValue("short_description") + "</p>";
html += "<p><b>Description:</b> " + rec.getValue("description") + "</p>";
html += "<p><b>Priority:</b> " + rec.getDisplayValue("priority") + "</p>";

html += "<br><hr><br>";

mergedHTML += html;
}

if (!mergedHTML)
return "";

// File name
var fileName = "Selected_Records.doc";

// Dummy record to attach the document
var dummy = new GlideRecord("sys_script");
dummy.initialize();
dummy.name = "Download Holder";
var dummyID = dummy.insert();

// Attach the HTML as Word file
var sa = new GlideSysAttachment();
var attachmentID = sa.write(dummy, fileName, "application/msword", mergedHTML);

return attachmentID;
}
});

 
 If my response was helpful, please mark it as the correct answer ✔️ to help others in the community find the solution easily.

View solution in original post

7 REPLIES 7

Ankur Bawiskar
Tera Patron
Tera Patron

@KanishkaS814962 

do you want to generate and add from client side (UI) or server side?

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

indersinghp
Tera Expert

Hi @KanishkaS814962 ,

You can achieve this requirement by implementing a UI Action. Specifically, you will need to configure a client-side UI Action together with a client-callable Script Include. Both components work in coordination to generate the Word document. The implementation details and code samples are provided below:

 

Here is the UI Action script:-

 

function onClick() {

    var ids = g_list.getChecked();   // returns comma-separated sys_ids

    if (!ids) {
        alert("Please select at least one record.");
        return;
    }

    // Call script include
    var ga = new GlideAjax('BGHDownloadUtils');
    ga.addParam('sysparm_name', 'downloadDoc');
    ga.addParam('sysparm_ids', ids);

    ga.getXML(function(response) {

        var attId = response.responseXML.documentElement.getAttribute("answer");

        if (!attId) {
            alert("Failed to generate document.");
            return;
        }

        // Start download
        window.location = "/sys_attachment.do?sys_id=" + attId;
    });

}
 
Here is the Script Include Script:-
 

var BGHDownloadUtils = Class.create();
BGHDownloadUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {

downloadDoc: function() {

var ids = this.getParameter('sysparm_ids');
if (!ids)
return "";

var idList = ids.split(',');

// This will hold the combined HTML
var mergedHTML = "";

// Loop through each selected record
for (var i = 0; i < idList.length; i++) {

var rec = new GlideRecord('incident'); // Change table if required
if (!rec.get(idList[i]))
continue;

// Build HTML content manually (NO TEMPLATE USED)
var html = "";

html += "<h2>Incident Details</h2>";
html += "<p><b>Number:</b> " + rec.getValue("number") + "</p>";
html += "<p><b>Short Description:</b> " + rec.getValue("short_description") + "</p>";
html += "<p><b>Description:</b> " + rec.getValue("description") + "</p>";
html += "<p><b>Priority:</b> " + rec.getDisplayValue("priority") + "</p>";

html += "<br><hr><br>";

mergedHTML += html;
}

if (!mergedHTML)
return "";

// File name
var fileName = "Selected_Records.doc";

// Dummy record to attach the document
var dummy = new GlideRecord("sys_script");
dummy.initialize();
dummy.name = "Download Holder";
var dummyID = dummy.insert();

// Attach the HTML as Word file
var sa = new GlideSysAttachment();
var attachmentID = sa.write(dummy, fileName, "application/msword", mergedHTML);

return attachmentID;
}
});

 
 If my response was helpful, please mark it as the correct answer ✔️ to help others in the community find the solution easily.

indersinghp
Tera Expert

Hi @KanishkaS814962 ,

You can achieve this requirement by implementing a UI Action. Specifically, you will need to configure a client-side UI Action together with a client-callable Script Include. Both components work in coordination to generate the Word document. The implementation details and code samples are provided below:

 

Here is the UI Action script:-

 

function onClick() {

    var ids = g_list.getChecked();   // returns comma-separated sys_ids

    if (!ids) {
        alert("Please select at least one record.");
        return;
    }

    // Call script include
    var ga = new GlideAjax('BGHDownloadUtils');
    ga.addParam('sysparm_name', 'downloadDoc');
    ga.addParam('sysparm_ids', ids);

    ga.getXML(function(response) {

        var attId = response.responseXML.documentElement.getAttribute("answer");

        if (!attId) {
            alert("Failed to generate document.");
            return;
        }

        // Start download
        window.location = "/sys_attachment.do?sys_id=" + attId;
    });

}
 
Here is the Script Include Script:-
 

var BGHDownloadUtils = Class.create();
BGHDownloadUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {

downloadDoc: function() {

var ids = this.getParameter('sysparm_ids');
if (!ids)
return "";

var idList = ids.split(',');

// This will hold the combined HTML
var mergedHTML = "";

// Loop through each selected record
for (var i = 0; i < idList.length; i++) {

var rec = new GlideRecord('incident'); // Change table if required
if (!rec.get(idList[i]))
continue;

// Build HTML content manually (NO TEMPLATE USED)
var html = "";

html += "<h2>Incident Details</h2>";
html += "<p><b>Number:</b> " + rec.getValue("number") + "</p>";
html += "<p><b>Short Description:</b> " + rec.getValue("short_description") + "</p>";
html += "<p><b>Description:</b> " + rec.getValue("description") + "</p>";
html += "<p><b>Priority:</b> " + rec.getDisplayValue("priority") + "</p>";

html += "<br><hr><br>";

mergedHTML += html;
}

if (!mergedHTML)
return "";

// File name
var fileName = "Selected_Records.doc";

// Dummy record to attach the document
var dummy = new GlideRecord("sys_script");
dummy.initialize();
dummy.name = "Download Holder";
var dummyID = dummy.insert();

// Attach the HTML as Word file
var sa = new GlideSysAttachment();
var attachmentID = sa.write(dummy, fileName, "application/msword", mergedHTML);

return attachmentID;
}
});

 
 If my response was helpful, please mark it as the correct answer ✔️ to help others in the community find the solution easily.