PowerShell:如何通过XmlTextWriter生成正确的空Excel Worksheet-XML
解决PowerShell中用XmlTextWriter生成正确Excel Worksheet XML的问题
我来帮你逐个搞定这些问题,让生成的XML完全符合预期:
问题1:编码为UTF-16而非UTF-8
你用StringBuilder存储XML内容时,.NET字符串默认是UTF-16编码,所以最终输出会是UTF-16。解决办法是改用MemoryStream来写入XML,之后再把流转换成UTF-8编码的字符串。
问题2:多余的r:xmlns属性
你错误地用了WriteStartAttribute来定义命名空间,这会生成反向的前缀属性。正确做法是用WriteAttributeString直接添加命名空间属性,不需要用WriteStartAttribute的方式。
问题3:无法同时设置默认命名空间和xmlns:r属性
创建worksheet元素时,要指定默认命名空间(第二个参数传默认命名空间的URI),然后再单独添加xmlns:r的属性即可。
问题4:异步方法运行异常
XmlTextWriter的异步方法在PowerShell里容易出现调度问题,而且这种简单的XML结构用同步方法足够高效还更可靠,建议直接改用同步方法。
修正后的完整代码
# 创建XML写入设置 $settings = [System.Xml.XmlWriterSettings]::new() $settings.Encoding = [System.Text.Encoding]::UTF8 $settings.Indent = $true # 可选:让XML格式化更易读 $settings.OmitXmlDeclaration = $false # 使用MemoryStream存储UTF-8编码的XML $stream = [System.IO.MemoryStream]::new() $wr = [System.Xml.XmlTextWriter]::Create($stream, $settings) # 写入XML声明(XmlWriter会自动处理,也可以手动写) $wr.WriteStartDocument($true) # 创建worksheet元素,指定默认命名空间 $wr.WriteStartElement("worksheet", "http://schemas.openxmlformats.org/spreadsheetml/2006/main") # 添加r前缀的命名空间属性 $wr.WriteAttributeString("xmlns", "r", $null, "http://schemas.openxmlformats.org/officeDocument/2006/relationships") # 创建sheetData元素(注意大小写:目标是<sheetData>,不是<sheetdata>) $wr.WriteStartElement("sheetData") $wr.WriteEndElement() # 关闭worksheet元素 $wr.WriteEndElement() # 完成写入并释放资源 $wr.Flush() $wr.Close() # 将MemoryStream转换为UTF-8字符串 $stream.Position = 0 $reader = [System.IO.StreamReader]::new($stream, [System.Text.Encoding]::UTF8) $resultXml = $reader.ReadToEnd() $reader.Close() $stream.Close() # 输出结果 $resultXml
生成的XML结果
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"> <sheetData /> </worksheet>
关键改动说明
- 用
MemoryStream替代StringBuilder,确保输出是UTF-8编码 - 改用同步的
WriteStartDocument、WriteStartElement等方法,避免异步调度问题 - 正确指定
worksheet的默认命名空间,通过WriteAttributeString添加xmlns:r属性 - 修正了
sheetdata的大小写(目标是驼峰式的sheetData)
这样就能完美生成你需要的worksheet.xml结构了。
内容的提问来源于stack exchange,提问作者Carsten
相关产品推荐
相关产品推荐

