Kirby
Kirby

Reputation: 2028

How to save a file in Outlook from Add-in [taskpane or otherwise]?

I have built an Office/Outlook add-in that interacts with my user's email messages.

I have the need/requirement to build/create and save a file to the desktop for my add-in user.

I have tried various methods with typical JavaScript solutions for the web. These solutions work only when the add-in is being used through OWA. These solutions also test successfully in Safari, FF, Chrome, etc ... but will not work in Outlook for Mac/Windows.

I have been searching [unsuccessfully,] the OfficeJS API documentation for a possible API method to save a file instead of writing my own in JavaScript.

Does such a thing exist?

Can an Outlook add-in create and save a file to the desktop for a user from "Outlook for Mac/Windows"?

Edit: While the documentation here (https://learn.microsoft.com/en-us/office/dev/add-ins/concepts/browsers-used-by-office-web-add-ins) suggests (for example) Outlook for Mac is running an embedded safari... it appears it is a much more locked down sandboxed version of Safari. Which leads me to the hypothesis, no amount of custom JavaScript will get me to my feature implementation.

Note: WRT to implementing my own JS to download a file (still unsuccessful, maybe a working hack exists here somewhere?)

// testing with a simple test image though will need to support more than images
const testBase64Image = '<insert_base64_string_of_a_jpg_image>';

downloadTempFile1(): void {
  const newFileName = 'test_download_image.jpg';
  const a = document.createElement("a"); // Create <a>
  a.target = "_blank"; // open in new tab
  // need special handling of certain content types?
  a.href = "data:octet-stream;base64," + testBase64Image; // Base64 Goes here
  a.download = newFileName; //File name Here
  a.click(); //Download file
}

downloadTempFile2(): void {
  window.location.href = 'data:application/octet-stream;base64,' + testBase64Image;
}

downloadTempFile3(): void {
  const blob = this.b64toBlob(testBase64Image, 'octet-stream');
  const blobUrl = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.download = 'test_download_image3.jpg';
  link.target = '_blank';
  link.href = URL.createObjectURL(blob);
  link.click();
}

b64toBlob = (b64Data, contentType='', sliceSize=512): Blob => {
  const byteCharacters = atob(b64Data);
  const byteArrays = [];
  for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    const slice = byteCharacters.slice(offset, offset + sliceSize);
    const byteNumbers = new Array(slice.length);
    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
      byteArrays.push(byteArray);
  }
  const blob = new Blob(byteArrays, {type: contentType});
  return blob;
}

Edit2: There exists Office.context.ui.openBrowswerWindow for some Client versions apparently, but I was able to use window.open() in this fashion.

openNewWindow(): void {
  const wnd = window.open('data:application/octet-stream;base64,' + base64Image);
  setTimeout(function() {
    wnd.close();
  }, 3000);
}

This will download the file in OWA, but will still not download the file in the desktop client.

Edit3: I was able to figure out that I needed to lock down my manifest to Office SDK Mailbox 1.8 (Requirements Set). I was also able to figure out that Outlook for Mac has a little toggle button in the top to switch from old to new UI and back. New UI does not support 1.8. 1.8 was required for window.open to operate correctly, but I have yet to be able to use window.open to download a file. I am still unable to use openBrowserWindowApi 1.1 yet as well.

Edit4: I decided to try using Office.context.ui.displayDialogAsync() and sending a message to the child window. While the displayDialogAsync will open a new window from the desktop client, it will not let me save a base64 file to the desktop for the user.

Upvotes: 1

Views: 1180

Answers (2)

Xeras
Xeras

Reputation: 3

It seems that Office.context.ui.openBrowserWindow() only works with urls beginning with http:// or https://. If the url looks like data:<mime-type;base64,<base64 encoded content> or blob:https://<url>/<uuid> (created by URL.createObjectURL()), it does not open a new window and it does not throw any error message.

For windows client the method should work. I tested FileSaver.js to do this job for me, which works perfectly fine in windows client, but not in mac client.

Are there any other possibility to download base64 content in "outlook for mac" without sending the data to a remote service?

Upvotes: 0

user7823505
user7823505

Reputation:

openBrowserWindow is the workaround for this. (We cannot download files directly from the Sandboxed IE or Edge Process). This should open an html page in the default browser, that the user can then download files via a link/etc.

https://learn.microsoft.com/en-us/javascript/api/office/office.ui?view=excel-js-preview#openBrowserWindow_url_

window.open() functions differently depending on if IE or Edge is the underlying rendering engine which can vary based on Office and Windows Version, which is whey OpenBrowserWindow was created.

See this link for information about IE/Edge WebView: https://developer.microsoft.com/en-us/office/blogs/microsoft-edge-webview-for-office-add-ins/

Upvotes: 1

Related Questions