In this article (catchy title I know), I will walk through, why you can’t simply insert secure images into a MS Word document and what you can do, to make it work. Walking through the scenarios, I will be using an Azure Active Directory Web Application as an example, which is based on MVC/Web API.
When you retrieve images from a secure resource (such as SharePoint), you will not be able to immediately insert them into a MS Word document. This is because the Office document does not have access to SharePoint.
If you insert images using the established HTML method, you will need an active internet connection and of course, access to the specific image:
As discussed before, you do not have access to the image on SharePoint Online from the context of the document, so we need to find a way to ‘localise’ the image.
From here, we can create a different image HTML string, this time using the Base64 value in the source attribute.
Unfortunately, this will not work either, and this is to do with the fact that the image is hosted in a secure site. It causes the canvas object to throw a security exception when you try to invoke the toDataUrl method against it (the image needs to be local to the script or have Cross Domain access allowed).
We have to work with what we have and in this particular scenario, we have access to the SharePoint Online REST API. Using this, we can get the specific image back by using a Proxy and seeing as we have the image object at that point, we can also return back the Base64 value of the image to the client.
So in our Web Application (MVC/Web API), we can create a new controller method which will do just that (remember you will need to plumb in the logic to get the authorisation header value as detailed in the example):
So now we are half way there (living on a prayer?). To insert the image into the MS Word document, we will switch the coercion type to Open XML (ooxml).
Great, now you may notice a few special tokens in the template:
- Base64 – The image base64 value
- Format – The image type, corrected (JPEG, PNG etc..)
These will get updated when we insert the snippet into the MS Word document, using the relevant image information (collected from the image URL and the Base64 value, retrieved from our Web API method).
Now, it goes without saying that you would not want to do this for every image, each and every time. The rule of thumb is to save the data locally against the image, in a data attribute for when the first insert happens. Once this is done, amend the image object to apply a special a CSS class, that you can use later to check if we have the data ‘localised’ or not. Then you can do something like this…
If a subsequent click of the image happens, you can use this local data attribute instead, thus limiting the amount of data calls (and only retrieving the data for the images that are being inserted into the document).