An Office service that supports add-ins to interact with objects in Office client applications.
Hello RahulK
Thank you for reaching out to Microsoft Q&A
Based on my research, the Word.DocumentCreated object returned by context.application.createDocument() does not provide any method to extract the document as Base64 without opening it and currently, tempDoc.open() is the only documented way to access a created document for Base64 extraction, which triggers the unwanted new window behavior.
Given this you can try using an in-place sanitization approach with workflow:
- Disable change tracking:
context.document.changeTrackingMode = Word.ChangeTrackingMode.off - Accept all revisions:
context.document.body.getTrackedChanges().acceptAll() - Remove content controls: Iterate
context.document.contentControlsand calldelete(false)to preserve inner content - Remove custom metadata: Delete items from
context.document.properties.customPropertiesandcontext.document.customXmlParts - Extract Base64: Use
Office.context.document.getFileAsync(Office.FileType.Compressed)and convert to Base64 - Restore original: Either use
context.document.undo()or save the original Base64 beforehand and restore viabody.insertFileFromBase64(originalBase64, Word.InsertLocation.replace)
Example for this approach:
async function getSanitizedBase64() {
return await Word.run(async (context) => {
const doc = context.document;
// Save original state
const originalBase64 = await getDocumentAsBase64();
// Sanitize
doc.changeTrackingMode = Word.ChangeTrackingMode.off;
doc.body.getTrackedChanges().acceptAll();
await context.sync();
const contentControls = doc.contentControls;
contentControls.load("items");
await context.sync();
for (let i = contentControls.items.length - 1; i >= 0; i--) {
contentControls.items[i].delete(true);
}
const customProps = doc.properties.customProperties;
customProps.load("items");
await context.sync();
for (let i = customProps.items.length - 1; i >= 0; i--) {
customProps.items[i].delete();
}
const customXmlParts = doc.customXmlParts;
customXmlParts.load("items");
await context.sync();
for (let i = customXmlParts.items.length - 1; i >= 0; i--) {
customXmlParts.items[i].delete();
}
await context.sync();
// Extract sanitized Base64
const sanitizedBase64 = await getDocumentAsBase64();
// Restore original
doc.body.insertFileFromBase64(originalBase64, Word.InsertLocation.replace);
await context.sync();
return sanitizedBase64;
});
}
function getDocumentAsBase64() {
return new Promise((resolve, reject) => {
Office.context.document.getFileAsync(Office.FileType.Compressed, { sliceSize: 4194304 }, (result) => {
if (result.status === Office.AsyncResultStatus.Succeeded) {
const file = result.value;
const sliceCount = file.sliceCount;
let slicesReceived = 0;
const docData = [];
const getSlice = (index) => {
file.getSliceAsync(index, (sliceResult) => {
if (sliceResult.status === Office.AsyncResultStatus.Succeeded) {
docData.push(sliceResult.value.data);
slicesReceived++;
if (slicesReceived === sliceCount) {
file.closeAsync();
const allBytes = new Uint8Array(docData.reduce((acc, arr) => acc + arr.length, 0));
let offset = 0;
docData.forEach(arr => {
allBytes.set(new Uint8Array(arr), offset);
offset += arr.length;
});
resolve(btoa(String.fromCharCode(...allBytes)));
} else {
getSlice(index + 1);
}
} else {
file.closeAsync();
reject(sliceResult.error);
}
});
};
getSlice(0);
} else {
reject(result.error);
}
});
});
}
Additionally, you can read here for more information:
Word.Document.changeTrackingMode
Hope my answer will help you.
If the answer is helpful, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.