窗外

Exporting SharePoint search result with a custom display template

In my recent project, I got a requirement to export the search result of SharePoint 2013 to a CSV file. Initially, I think it was simple. I could probably extend the search result web part, generate the CSV on the server side and send it to the client. But when I looked at it in detail, I doubted if a search extension web part was a good idea. It could be way too heavy for such a simple requirement. It didn’t fit into our project very well too, because we are trying to leverage the new app model as much as possible, and to limit the server side customization as minimum as possible.

So I decided to explore another way, to use the display template to get the search result and to generate the CSV with JavaScript. Here are then two questions to answer.

  1. Is it possible to get all search result in display template easily?
  2. How to generate a file with JavaScript on the fly and prompt the user to download it?

Fortunately, I managed to figure out the answers of the above two questions. And I will show you how I did it in this post.

First of all, I created a control display template based on the OOTB Default Result template. I wrapped all my JavaScript code in a custom js file, exportresult.js, and uploaded it to the Style Library. I then linked the js in the display template with the following code:

<body>
  <script>
    $includeScript(this.url, "~sitecollection/Style%20Library/export/exportresult.js");
  </script>
...
</body>

I hooked my JavaScript function onto ctx.OnPostRender() so that it could be called after the page is rendered. I also added a button on top of the search result for user to trigger the exporting:

<div style="display: table-cell">
   <a id="idExportSearchResults" href="#">Export Result</a>
</div>

There is almost no useful document regarding to the JavaScript object used in the display template. So I have to try and debug the JavaScript code to figure out where the search result is stored. In the ctx.ListData object, there is a ResultTables array which stores several result tables. Based on my testing, the first item of this array is the search result shown in the search result web part. The 2nd item could be the result for refinement. So I used the following js code to export the result with the required metadata.

var propArray = ["Author", "Created", "ExternalMediaURL", "LastModifiedTime", "Path"];
var exportedResult = new Array();
// Get only the required the managed properties.
ctx.ListData.ResultTables[0].ResultRows.forEach(function (row) {
   var obj = new Object;
   for (var i = 0; i < propArray.length; i++) {
     obj[propArray[i]] = row[propArray[i]] ? row[propArray[i]] : "";
   }
   exportedResult.push(obj)
});

Finally, I need a way to export the data to a file with JavaScript. I actually found a very helpful post here. All credit of the way I used following goes to this post. The following code shows the idea.

var showSave;
// Only works with IE10 or later.
if (window.Blob && navigator.msSaveBlob) {
  showSave = function (data, name, mimeType) {
    resultBlob = new Blob([data], { type: mimeType });
    navigator.msSaveBlob(resultBlob, name);
  }
}

With all the above, I can fulfill the requirement now. The code only works for IE10 and later. It could be extended to support other browsers. If you are interested in extending the code, feel free to fork it on Github.

3 comments

  1. Nice post.. This code only export the current page result to csv. This is not exporting full result set. If you solution to export full set please share.

    1. Thanks Sam. I didn’t play with the code for quite a while. You can try if you can extend it to what you want.

Leave a Reply

Your email address will not be published. Required fields are marked *