我们有一个系统可以在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");
}
});
}
有什么建议吗?
答案 0 :(得分:1)
由于重新压缩工作,内容似乎很好。
所以听起来拉链过程有问题。因此,在7-Zip中打开损坏的docx,并注意&#34;方法&#34;中的值。列(特别是对于customXML \ item.xml)。
将该值与工作docx进行比较 - 它是相同还是不同?方法&#34;放气&#34;的工作原理。
答案 1 :(得分:0)
我遇到了同样的问题,原来这是由于编码。 序列化/反序列化时是否已指定相同的编码?
答案 2 :(得分:0)
一对建议 一个。试试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
}