/* * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. * See LICENSE in the project root for license information. */ /* global document, Office, Word */ let HTMLContent = ""; var totalSliceCount; const uatURL = "https://transportalapi-uat2.azurewebsites.net/api"; const localHostURL = "http://localhost:3000"; Office.onReady((info) => { if (info.host === Office.HostType.Word) { const appBody = document.getElementById("app-body"); const runButton = document.getElementById("run"); const saveButton = document.getElementById("save-html"); const getButton = document.getElementById("get-html"); const saveBase64Button = document.getElementById("save-base64"); const getBase64Button = document.getElementById("get-base64"); const clearButton = document.getElementById("clear-document"); if (appBody) { appBody.style.display = "flex"; } if (runButton) { runButton.onclick = run; } if (clearButton) { clearButton.onclick = () => { cleanDocument(); } } if (saveButton) { saveButton.onclick = () => { console.log("save html"); getBodyHTML(); }; } if (getButton) { getButton.onclick = () => { console.log("get html"); insertUsingHTML() }; } if (saveBase64Button) { saveBase64Button.onclick = () => { console.log("save base64"); sendFile(true); cleanDocument(); }; } if (getBase64Button) { getBase64Button.onclick = () => { console.log("get base64"); insertUsingBase64(); }; } } }); async function getBodyHTML() { await Word.run(async (context) => { console.log("getBodyHTML"); const body = context.document.body; context.load(body) const bodyHTML = body.getHtml(); // const bodyHTML = body.getOoxml(); await context.sync(); HTMLContent = bodyHTML.value; HTMLContent = bodyHTML.value.trim(); // Remove leading and trailing spaces HTMLContent = await handleTableShrinkChanges(HTMLContent); console.log("HTMLContent", HTMLContent); cleanDocument(); }); } async function insertUsingHTML() { await Word.run(async (context) => { var decodedHtmlContent = HTMLContent; Office.context.document.setSelectedDataAsync(decodedHtmlContent, { coercionType: Office.CoercionType.Html }, function (asyncResult) { if (asyncResult.status == Office.AsyncResultStatus.Failed) { write(asyncResult.error.message); } }); let cursorOrSelection = context.document.getSelection(); context.load(cursorOrSelection); cursorOrSelection.select('end'); await context.sync(); }); } async function insertUsingBase64(item) { await Word.run(async (context) => { try { // Assuming base64Content is defined and contains the base64 string of the file to be inserted var base64Content = item; let cursorOrSelection = context.document.getSelection(); context.load(cursorOrSelection); cursorOrSelection.clear(); cursorOrSelection.insertFileFromBase64(base64Content, Word.InsertLocation.end); cursorOrSelection.select('end'); await context.sync(); } catch (error) { console.error('An error occurred:', error.message); } }); } async function handleTableShrinkChanges(HTMLContent) { await Word.run(async (context) => { var pattern = /(]*style="[^"]*)width:\s*0px;([^"]*"[^>]*>)/gi; HTMLContent = HTMLContent.replace(pattern, "$1$2"); }); return HTMLContent; } async function cleanDocument() { await Word.run(async (context) => { const body = context.document.body; // Load the paragraphs and tables in the body body.load("paragraphs, tables"); return context.sync() .then(function () { // Iterate through the paragraphs and remove them body.paragraphs.items.forEach(function (paragraph) { paragraph.delete(); }); // Iterate through the tables and remove them body.tables.items.forEach(function (table) { table.delete(); }); // Sync to apply the changes return context.sync(); }); }); } // Get all of the content from a PowerPoint or Word document in 100-KB chunks of text. function sendFile(modifySegmentName) { Office.context.document.getFileAsync("compressed", { sliceSize: 100000 }, function (result) { if (result.status === Office.AsyncResultStatus.Succeeded) { // Get the File object from the result. var myFile = result.value; var state = { file: myFile, counter: 0, sliceCount: myFile.sliceCount }; setTotalSliceCount(state) updateStatus("Getting file of " + myFile.size + " bytes"); getSlice(state, modifySegmentName); } else { updateStatus(result.status); } }); } // Create a function for writing to the status div. function updateStatus(message) { // var statusInfo = $('#status'); // statusInfo[0].innerHTML += message + "
"; console.log(message) } function setTotalSliceCount(state) { totalSliceCount = state.sliceCount; } // Get a slice from the file and then call sendSlice. function getSlice(state, modifySegmentName) { state.file.getSliceAsync(state.counter, function (result) { if (result.status == Office.AsyncResultStatus.Succeeded) { updateStatus("Sending piece " + (state.counter + 1) + " of " + state.sliceCount); sendSlice(result.value, state, modifySegmentName); } else { updateStatus(result.status); } }); } function sendSlice(slice, state, modifySegmentName) { var data = slice.data; // If the slice contains data if (data) { console.log("data: ", data) // Convert byte array to base64 string var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(data))); // Create the payload object var payload = { // isModifiedSegment: isSavingSegmentOnEdit, sliceNumber: slice.index, data: base64String, segmentName: modifySegmentName ? tempSegMentName + ' Modified' : tempSegMentName }; // Use fetch to send the request fetch(`${localHostURL}/Segment/UploadSlice`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': auth, 'Organizationid': orgId, 'Userid': userLoggedInId }, body: JSON.stringify(payload) }) .then(response => { if (response.ok) { updateStatus("Sent " + slice.size + " bytes."); state.counter++; if (state.counter < state.sliceCount) { getSlice(state); } else { closeFile(state, modifySegmentName); } } else { updateStatus("Error sending slice: " + response.statusText); } }) .catch(error => { updateStatus("Error sending slice: " + error.message); }); } } function closeFile(state, modifySegmentName) { // Close the file when you're done with it. state.file.closeAsync(function (result) { // If the result returns as a success, the // file has been successfully closed. if (result.status === Office.AsyncResultStatus.Succeeded) { updateStatus("File closed."); assembleFile(tempSegMentName, totalSliceCount, modifySegmentName); } else { updateStatus("File couldn't be closed."); } }); } function assembleFile(fileName, totalSlices, modifySegmentName) { // Encode the fileName to handle spaces and special characters in the URL const encodedFileName = encodeURIComponent(modifySegmentName ? tempSegMentName + ' Modified' : tempSegMentName); // Construct the URL with query parameters const url = `${localHostURL}/Segment/AssembleFile?segmentName=${encodedFileName}&totalSlices=${totalSlices}`; // Create a fetch request fetch(url, { method: 'POST', // Use POST method if you are modifying data on the server headers: { 'Content-Type': 'application/json', // Adjust this if your endpoint requires different headers 'Authorization': auth, 'Organizationid': orgId, 'Userid': userLoggedInId } }) .then(response => response.json()) // Parse the JSON response .then(data => { console.log('Success:', data); // Handle success if(isAddInOpenedInSegmentEditor && currentSegmentID != 0 && isSavingSegmentOnEdit) { initiateReplacingSegments(); } else { // hideLoader(); // closeDialog(); // getSegmentData() parentLoader.bigLoader.hide(); } }) .catch((error) => { console.error('Error:', error); // Handle error }); } export async function run() { return Word.run(async (context) => { /** * Insert your Word code here */ // insert a paragraph at the end of the document. const paragraph = context.document.body.insertParagraph("Hello World", Word.InsertLocation.end); // change the paragraph color to blue. paragraph.font.color = "blue"; await context.sync(); }); }