OpenXml Excel替换单元格带格式文本失效问题咨询
解决OpenXml替换带格式Excel文本失效的问题
你的问题出在带格式的文本在SharedString中的结构和纯文本不同:
- 无格式文本的SharedStringItem直接包含一个
<t>元素,你的代码能直接命中替换; - 带格式的文本(如加粗)会被包装在
<r>(Run)元素里,每个Run对应一套格式,你的代码直接替换SharedStringItem的FirstChild,要么会把整个Run(包含格式)替换掉,要么根本找不到正确的Text元素。
修正思路是遍历所有Run元素,再逐个处理每个Run下的Text,保留原有的格式设置:
using var Doc = SpreadsheetDocument.Open(CXmlDoc.GetExecutingPath() + "Test.xlsx", true); var nDoc = Doc.Clone(CXmlDoc.GetExecutingPath() + "Test1.xlsx"); var sstPart = nDoc.WorkbookPart!.GetPartsOfType<SharedStringTablePart>().FirstOrDefault(); if (sstPart?.RootElement == null) return; // 遍历所有共享字符串项 foreach (var sharedStringItem in sstPart.RootElement.Elements<SharedStringItem>()) { // 遍历当前项里的所有Run(带格式的文本都在Run里) foreach (var run in sharedStringItem.Elements<Run>()) { var textElement = run.Elements<Text>().FirstOrDefault(); if (textElement == null || !textElement.Text.Contains("test")) continue; // 替换文本,保留Run的格式 textElement.Text = textElement.Text.Replace("test", "NewText"); } } // 保存更改到新文件 nDoc.Save();
补充说明:
- 上述代码会处理单个Run内的带格式文本,比如整个"test"是加粗的情况,替换后"NewText"会保留原加粗格式;
- 如果遇到"test"被拆分到多个Run的情况(比如"te"加粗,"st"正常),需要额外处理文本拼接和格式合并逻辑,这属于更复杂的场景,可根据实际需求扩展;
- 必须调用
nDoc.Save()才能把更改写入到新文件里,你原来的代码漏掉了这一步。
内容的提问来源于stack exchange,提问作者s k
相关产品推荐
相关产品推荐

