【问题标题】:Editing custom XML part in word document sometimes corrupts document在 Word 文档中编辑自定义 XML 部分有时会损坏文档
【发布时间】:2014-05-15 08:27:15
【问题描述】:

我们有一个系统可以在 Word 文档中存储一些自定义模板数据。有时,更新此数据会导致 Word 抱怨文档已损坏。发生这种情况时,如果我解压缩 docx 文件并将其内容与以前的版本进行比较,唯一的区别似乎是 customXML\item.xml 文件中的预期变化。如果我使用 7zip 重新压缩内容,它似乎可以正常工作(Word 不再抱怨文档已损坏)。

(简化的)代码:

void CreateOrReplaceCustomXml(string filename, MyCustomData data)
{
    using (var doc = WordProcessingDocument.Open(filename, true))
    {
        var part = GetCustomXmlParts(doc).SingleOrDefault();
        if (part == null)
        {
            part = doc.MainDocumentPart.AddCustomXmlPart(CustomXmlPartType.CustomXml);
        }

        var serializer = new DataContractSerializer(typeof(MyCustomData));
        using (var stream = new MemoryStream())
        {
            serializer.WriteObject(stream, data);
            stream.Seek(0, SeekOrigin.Begin);
            part.FeedData(stream);
        }
    }
}

IEnumerable<CustomXmlPart> GetCustomXmlParts(WordProcessingDocument doc)
{
    return doc.MainDocumentPart.CustomXmlParts
        .Where(part =>
        {
            using (var stream = doc.Package.GePart(c.Uri).GetStream())
            using (var streamReader = new StreamReader(stream))
            {
                return streamReader.ReadToEnd().Contains("Some.Namespace");
            }
        });
}

有什么建议吗?

【问题讨论】:

  • 是否可以发布复制样本?

标签: c# zip openxml docx openxml-sdk


【解决方案1】:

由于重新压缩有效,看来内容格式正确。

所以听起来 zip 过程有问题。因此,在 7-Zip 中打开损坏的 docx,并记下“方法”列中的值(尤其是 customXML\item.xml)。

将该值与工作 docx 进行比较 - 它是相同的还是不同的?方法“放气”有效。

【讨论】:

  • 一样——一切都是“放气”
  • 好的,很好。我会专注于你的 C# 代码。当更新使数据变短或变长,或者没有模式时,是否会出现问题?重新压缩前后的打包大小(以 7-Zip 报告)是否相同?
  • 这帮助我找出了我的问题,很高兴与代表一起奖励它:) 我的实际问题是将完成的 Word 文档写入文件...
【解决方案2】:

我遇到了同样的问题,结果证明这是由于编码。 序列化/反序列化时是否已经指定了相同的编码?

【讨论】:

    【解决方案3】:

    几个建议 一种。试试 doc.Package.Flush();将数据写回自定义 xml 后。 湾。您可能必须删除所有自定义零件并添加新的自定义零件。我们正在使用以下代码,它似乎工作正常。

    public static void ReplaceCustomXML(WordprocessingDocument myDoc, string customXML)
        {
    
            MainDocumentPart mainPart = myDoc.MainDocumentPart;
            mainPart.DeleteParts<CustomXmlPart>(mainPart.CustomXmlParts);
            CustomXmlPart customXmlPart =     mainPart.AddCustomXmlPart(CustomXmlPartType.CustomXml);
            using (StreamWriter ts = new StreamWriter(customXmlPart.GetStream()))
            {
                ts.Write(customXML);
                ts.Flush();
                ts.Close();
            }
        }
    
    public static MemoryStream GetCustomXmlPart(MainDocumentPart mainPart)
        {
            foreach (CustomXmlPart part in mainPart.CustomXmlParts)
            {
                using (XmlTextReader reader =
                    new XmlTextReader(part.GetStream(FileMode.Open, FileAccess.Read)))
                {
                    reader.MoveToContent();
                    if (reader.Name.Equals("aaaa", StringComparison.OrdinalIgnoreCase))
                    {
                        string str = reader.ReadOuterXml();
                        byte[] byteArray = Encoding.ASCII.GetBytes(str);
                        MemoryStream stream = new MemoryStream(byteArray);
    
                        return stream;
                    }
                }
            }
    
            return null; //result;
        }
    
    using (WordprocessingDocument myDoc = WordprocessingDocument.Open(ms, true))
                    {
                        StreamReader reader = new StreamReader(memStream);
                        string FullXML = reader.ReadToEnd();
                        ReplaceCustomXML(myDoc, FullXML);
    
                        myDoc.Package.Flush();
    
                        //Code to save file
                    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-06
      • 1970-01-01
      • 2014-07-09
      • 1970-01-01
      相关资源
      最近更新 更多