I'm working on a Word add-in using the Office JS API and am building a converter that changes the selected text into a different format.
I’m not encountering any issues when the selection is a paragraph or when selecting an entire table. However,
I’m facing a problem when selecting multiple individual cells within a table. For example, if I select 5 cells in a column and try to print the selected text, I only get the text from the last cell (in the image, that’s row 101).
I’ve attached my code and an image of the table for better context. I need to retrieve the text from all the selected cells. How can I achieve this?
export async function convertSelectionFromPane() {
return Word.run(async (context) => {
const trimTrailingBreaks = (s) => (s || "").replace(/[\r\n\u000B\u2028\u2029]+$/g, "");
// Get ignore list
const ignoreList = getIgnoreList();
const selection = context.document.getSelection();
selection.load("text");
await context.sync();
const text = selection.text || "";
if (!text.trim()) return;
console.log("[Pane] Selection text:", text);
// Try to get text ranges for better granular control
const delimiters = ["\r", "\n", "\v", "\u000B", "\u2028", "\u2029"];
const textRanges = selection.getTextRanges(delimiters, true);
context.load(textRanges, "items");
await context.sync();
// If we have multiple ranges, process them individually
if (textRanges.items.length > 1) {
textRanges.items.forEach((tr) => tr.load("text"));
await context.sync();
for (let i = textRanges.items.length - 1; i >= 0; i--) {
const tr = textRanges.items[i];
const txt = tr.text || "";
if (!txt) continue;
console.log(`[Pane] Sub-range #${i} text:`, txt);
const converted = await convertTextWithIgnoreList(txt, ignoreList);
tr.insertText(trimTrailingBreaks(converted), Word.InsertLocation.replace);
await context.sync();
}
} else {
// Single range or no ranges - convert the entire selection
console.log("[Pane] Converting entire selection");
const converted = await convertTextWithIgnoreList(text, ignoreList);
selection.insertText(trimTrailingBreaks(converted), Word.InsertLocation.replace);
await context.sync();
}
});
}

textproperty. Just before thecontext.syncline add the lineselection.load("text");selection.load("text");part in the post. I’ve now added the complete code. There were some additional parts of the logic that might have caused confusion earlier, which is why I initially shared only a minimal version. I hope the full code provides better context now.