如何用Office Add-in JavaScript API查找段落中的下标/上标符号
问题描述
我的需求和查找选中内容中的加粗单词类似,但要找的不是空格分隔的单词,而是段落里格式为下标或上标的字母数字字符(比如words<sub>like</sub><sup>this</sup>这类),最终要把这些字符用<sub>和<sup>标签包裹,例如把404<sup>2</sup>转换为404<sup>2</sup>。
以下是对应的Python COM实现代码:
def paragraph_to_html(doc, paragraph): rng = doc.Range(paragraph.Range.Start, paragraph.Range.End - 1) rng.Find.Text = '' rng.Find.Font.Superscript = True while rng.Find.Execute(): rng.InsertBefore('<sup>') rng.InsertAfter('</sup>') rng.Font.Superscript = False rng = doc.Range(rng.End, paragraph.Range.End - 1)
我想用JavaScript Office Add-in改写这段代码,请问:
- 如何查找下标和上标字符?
- 如果无法直接查找,如何遍历段落中的每个字符,检查其
font.subscript是否为true?
解决方案
方法一:使用Office JavaScript API的Find功能
Office JS的Range.find接口支持通过字体属性匹配内容,逻辑和你Python COM的实现一致,以下是查找上标的示例代码:
async function wrapSuperscriptInTags() { await Word.run(async (context) => { const paragraph = context.document.selectedParagraphs.getFirst(); let range = paragraph.getRange('Start', 'End'); // 设置查找规则:匹配所有上标格式内容 const findOptions = context.createFindOptions(); findOptions.font.superscript = true; findOptions.matchWildcards = false; let foundRange = range.find.findFirst(findOptions); await context.sync(); // 循环处理所有匹配项 while (foundRange) { // 插入标签 foundRange.insertText('<sup>', 'Before'); foundRange.insertText('</sup>', 'After'); // 取消上标格式,避免重复匹配 foundRange.font.superscript = false; // 更新查找范围,从当前匹配项末尾开始 range = paragraph.getRange(foundRange.end, 'End'); foundRange = range.find.findFirst(findOptions); await context.sync(); } }).catch(error => { console.error(error); }); }
查找下标只需将findOptions.font.superscript = true改为findOptions.font.subscript = true即可。
方法二:遍历段落字符检查格式
如果Find功能无法满足需求,可以逐个遍历段落字符,检查字体格式:
async function wrapSubSupByTraversing() { await Word.run(async (context) => { const paragraph = context.document.selectedParagraphs.getFirst(); const textRange = paragraph.getRange('Start', 'End'); textRange.load('text, length'); await context.sync(); let currentTag = null; // 记录当前处理的标签类型(sub/sup) let startIndex = 0; // 遍历每个字符 for (let i = 0; i < textRange.length; i++) { const charRange = textRange.getRange(i, i + 1); charRange.load('font/superscript, font/subscript'); await context.sync(); const isSup = charRange.font.superscript; const isSub = charRange.font.subscript; // 处理上标逻辑 if (isSup) { if (!currentTag || currentTag !== 'sup') { // 关闭之前的标签(如果有) if (currentTag) { textRange.getRange(startIndex, i).insertText(`</${currentTag}>`, 'After'); await context.sync(); } currentTag = 'sup'; startIndex = i; // 插入起始标签 textRange.getRange(i, i).insertText('<sup>', 'Before'); await context.sync(); // 插入后段落长度变化,调整索引 i += '<sup>'.length; textRange.load('length'); await context.sync(); } } else if (isSub) { // 处理下标逻辑,和上标逻辑一致 if (!currentTag || currentTag !== 'sub') { if (currentTag) { textRange.getRange(startIndex, i).insertText(`</${currentTag}>`, 'After'); await context.sync(); } currentTag = 'sub'; startIndex = i; textRange.getRange(i, i).insertText('<sub>', 'Before'); await context.sync(); i += '<sub>'.length; textRange.load('length'); await context.sync(); } } else { // 当前字符不是下标/上标,关闭标签 if (currentTag) { textRange.getRange(startIndex, i).insertText(`</${currentTag}>`, 'After'); await context.sync(); currentTag = null; } } } // 处理段落末尾未关闭的标签 if (currentTag) { textRange.getRange(startIndex, textRange.length).insertText(`</${currentTag}>`, 'After'); await context.sync(); } // 取消所有下标/上标格式 textRange.font.superscript = false; textRange.font.subscript = false; await context.sync(); }).catch(error => { console.error(error); }); }
注意事项
- 所有操作需包裹在
Word.run中,确保上下文同步 - 插入标签后段落长度会变化,需重新加载长度并调整遍历索引
- 连续的下标/上标字符要避免重复插入标签
内容的提问来源于stack exchange,提问作者NotAProgrammer
相关产品推荐
相关产品推荐

