使用OpenXml更新SharePoint上Docx文件遇流写入异常求解
问题原因
HttpClient.GetStreamAsync从SharePoint获取的流是只读流(CanWrite为false,CanSeek为false),而调用WordprocessingDocument.Open(docStream, true)时,第二个参数true要求流必须支持读写和查找操作,因此触发The stream was not opened for writing异常。
解决步骤
- 将只读的网络流复制到
MemoryStream——这是一种支持读写、查找操作的内存流,满足OpenXml的写入要求 - 修改文档内容后,将修改后的文本写回文档部件
- 重置流指针到开头,确保后续可正确读取修改后的内容
修正后的代码
Stream docStream = await _httpClient!.GetStreamAsync(uri); // 把只读网络流转成可读写的MemoryStream var memoryStream = new MemoryStream(); await docStream.CopyToAsync(memoryStream); memoryStream.Position = 0; using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(memoryStream, true)) { // 读取原文档内容 string docText; using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream())) { docText = sr.ReadToEnd(); } // 替换文本 Regex regexText = new Regex("OldText"); docText = regexText.Replace(docText, "NewText"); // 将修改后的内容写回文档部件 using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create))) { sw.Write(docText); } } // 重置指针到开头,返回修改后的流 memoryStream.Position = 0; return memoryStream;
关键注意事项
- 原代码仅获取了
FileMode.Create的流但未写入内容,这会导致文档内容丢失,修正后需添加StreamWriter完成写入 - 返回流前必须重置指针到起始位置,否则调用方读取时会从流的末尾开始,无法获取有效内容
MemoryStream的生命周期需调整,避免在using块内被提前释放,确保返回的流可被外部正常使用
内容的提问来源于stack exchange,提问作者Bohdan
相关产品推荐
相关产品推荐

