There are a lot of blogs out there which touch on how to export SharePoint search results. However my requirement was to export the results AFTER using the refinement panel to filter deep down into the people search. Fortunately I had previously dabbled a bit with extracting search parameters after refining search results.
A short recap of my previous blog:
A simple people search url can look like this:
https://{host}/search/Pages/peopleresults.aspx?k=test
After using the filters the query transforms to this:
You can still spot some of our keywords but mostly the result behind the hash is encoded gibberish.
Get the Query
First step is to pull the query from current querystring to get the information behind the hash (#), after filtering results with the refiners the query gets transformed and added after the hash. If there is no hash, no transformation is needed, then collect the original query after the keyword ‘k’ parameter and return..
function changesearchquery() { var hash = ""; var fullUrl = window.location.href; var i = fullUrl.indexOf("#"); if (i > -1) { hash = fullUrl.substring(i); } else { var currentSearch = (location.href.indexOf("k=") > 0) ? location.href.split("k=")[1] : ""; //if page count exists currentSearch = (currentSearch.indexOf("#s=") > 0) ? currentSearch.split("#s=")[0] : currentSearch; return currentSearch; }
Transform the Gibberish
Next step is to transform the query gibberish to usable search properties. Parse the result to JSON so we can start extracting the data.
var hashQuery = []; var queryGroups = hash.split("#"); for (var i = 1; i < queryGroups.length; i++) { if (queryGroups[i].length > 0) { var keyValue = queryGroups[i].split("=", 2); var key = keyValue[0]; var encodedValue = keyValue[1]; if (key === "Default") { // json string format var jsonStringValue = decodeURIComponent(encodedValue); var safejsonStringValue = jsonStringValue.replace("’", "\’").replace("'", "\'"); var queryObject = JSON.parse(safejsonStringValue); hashQuery[key] = queryObject; } else if (key === "k") { // simple format hashQuery[key] = encodedValue; } } }
Rebuild your Query
Extract the search properties and rebuild the query as a usable search api call.
var filterprops = ''; if (hashQuery["Default"] !== undefined) { // json string format if (hashQuery["Default"].k !== undefined && hashQuery["Default"].k.length > 0) { filterprops += "\"" + hashQuery["Default"].k + "\""; } for (var i = 0; i < hashQuery["Default"].r.length; i++) { if (hashQuery["Default"].r[i].m !== null) { // check if 'm' contains data for (var n = 0; n < hashQuery["Default"].r[i].t.length; n++) { var keywordkey = hashQuery["Default"].r[i].n; var keywordvalue = hashQuery["Default"].r[i].m[hashQuery["Default"].r[i].t[n]]; filterprops = addFilterProp(keywordkey, keywordvalue, filterprops); } } else { for (var n = 0; n < hashQuery["Default"].r[i].t.length; n++) { var tvalue = hashQuery["Default"].r[i].t[n]; if (tvalue.indexOf('ǂ') !== -1) { // value is HEX type var keywordkey = hashQuery["Default"].r[i].n; var keywordvalue = hex2a(tvalue); filterprops = addFilterProp(keywordkey, keywordvalue, filterprops); } else { // simple format var keywordkey = hashQuery["Default"].r[i].n; var keywordvalue = tvalue; filterprops = addFilterProp(keywordkey, keywordvalue, filterprops); } } } } } else if (hashQuery["k"] !== undefined) { // simple value (no json) filterprops += "\"" + hashQuery["k"] + "\""; } return filterprops; } function addFilterProp(keywordKey, keywordValue, filterProps) { if (!filterProps === '') { filterProps += " AND "; } filterProps += "\"" + keywordKey + "\":\"" + keywordValue + "\" "; return filterProps; } function hex2a(hexx) { var hex = hexx.toString(); hex = hex.replace('"', '').replace('"', '').replace('ǂ', '').replace('ǂ', ''); var str = ''; for (var i = 0; i <= (hex.length - 2); i += 2) { str += String.fromCharCode(parseInt(hex.substring(i, i + 2), 16)); } return str; }
Query through REST
Run the query through the REST api (note: Max 500 items can be retrieved through the rest api)
function getSearchResultsUsingREST(queryText) { Results = { element: '', url: '', init: function (element) { Results.element = element; Results.url = _spPageContextInfo.webAbsoluteUrl + "/_api/search/query?querytext='" + queryText + "'&sourceid='bbb05724-f652-4b86-beff-af1284e8e789'&selectproperties='PersonellID,PreferredName,JobTitle,WorkEmail,WorkPhone,MobilePhone,Office1,Room,Office2,Room2,Practice,Team,KnowledgeGroup,ProfessionGroup,Jurisdiction,Secretary'"; }, load: function () { $.ajax( { url: Results.url, method: "GET", headers: { "accept": "application/json;odata=verbose" }, success: Results.onSuccess, error: Results.onError } ); }, onSuccess: function (data) { var results = data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results; var propArray2 = ["Personell ID", "Name", "Job Title", "Work e-mail", "Work phone", "Mobile phone", "Primary office", "Primary room number", "Secondary office", "Secondary room number", "Practice group", "Team", "Knowledge group", "Profession group", "Jurisdiction", "Secretary"]; var exportedResult2 = new Array(); // Get only the required the managed properties. for (var j = 0; j < results.length; j++) { var obj = new Object; for (var i = 0; i < propArray2.length; i++) { if (results[j].Cells.results[i + 2].Value !== null) { if (results[j].Cells.results[i + 2].Value.match(/"|,/)) { results[j].Cells.results[i + 2].Value = '"' + results[j].Cells.results[i + 2].Value + '"'; } } obj[propArray2[i]] = results[j].Cells.results[i + 2].Value ? results[j].Cells.results[i + 2].Value : ""; } exportedResult2.push(obj); } showSave(ConvertToCSV(JSON.stringify(exportedResult2), propArray2), "ExportedSearchResult.csv", "text/csv; charset=UTF-8"); }, onError: function (err) { alert(JSON.stringify(err)); } }; Results.init($('#resultsDiv')); Results.load(); }
Save it!
And save and format as CSV:
function showSave(data, name, mimeType) { resultBlob = new Blob([data], { type: mimeType }); if (window.navigator.userAgent.indexOf("MSIE ") > 0 || !!window.navigator.userAgent.match(/Trident.*rv:11./)) { navigator.msSaveBlob(resultBlob, name); } else //other browsers : Chrome/FireFox (Supported Data URIs) { //creating a temporary HTML link element (they support setting file names) var link = document.createElement('a'); var url = URL.createObjectURL(resultBlob); link.setAttribute("href", url); link.setAttribute("download", "ExportedSearchResult.csv"); link.style.visibility = 'hidden'; document.body.appendChild(link); link.click(); document.body.removeChild(link); } } function ConvertToCSV(objArray, headerArray) { var array = typeof objArray !== 'object' ? JSON.parse(objArray) : objArray; var str = ''; // Create header row. var headerLine = ''; for (var i = 0; i < headerArray.length; i++) { if (headerLine !== "") { headerLine += ','; } headerLine += headerArray[i]; } str += headerLine + '\r\n'; // Create CSV body. for (var l = 0; l < array.length; l++) { var line = ''; for (var index in array[l]) { if (line !== '') { line += ','; } var isnum = /^\+?\d+$/.test(array[l][index]); if (isnum) { line += '"=""' + array[l][index] + '"""'; } else { line += array[l][index]; } } str += line + '\r\n'; } return str; }
All this can come together by adding a button to your page:
<div style="display: table-cell;"><a id="idExportSearchResults" href="#">Export Result</a></div>
which calls:
function getExcel(ctx) { var a = document.getElementById("idExportSearchResults"); var currentSearch = changesearchquery(); var decodedCurrentSearch = decodeURIComponent(currentSearch); getSearchResultsUsingREST(decodedCurrentSearch); }
Download the full js file here.
The post Export SharePoint search results to CSV after refining appeared first on Mavention.