C# 打开保存word文档的XML会生成损坏的文件
虽然我对开放XML世界还不熟悉,但我在使用它时已经遇到了一些麻烦/问题。大多数问题都很容易解决,但我无法回避这个问题:C# 打开保存word文档的XML会生成损坏的文件,c#,ms-word,ms-office,openxml,C#,Ms Word,Ms Office,Openxml,虽然我对开放XML世界还不熟悉,但我在使用它时已经遇到了一些麻烦/问题。大多数问题都很容易解决,但我无法回避这个问题: public class ReportDocument : IDisposable { private MemoryStream stream; private WordprocessingDocument document; private MainDocumentPart mainPart; public byte[] DocumentDa
public class ReportDocument : IDisposable
{
private MemoryStream stream;
private WordprocessingDocument document;
private MainDocumentPart mainPart;
public byte[] DocumentData
{
get
{
this.document.ChangeDocumentType(WordprocessingDocumentType.MacroEnabledDocument);
byte[] documentData = this.stream.ToArray();
return documentData;
}
}
public ReportDocument()
{
byte[] template = DocumentTemplates.SingleReportTemplate;
this.stream = new MemoryStream();
stream.Write(template, 0, template.Length);
this.document = WordprocessingDocument.Open(stream, true);
this.mainPart = document.MainDocumentPart;
}
public void SetReport(Report report)
{
Body body = mainPart.Document.Body;
var placeholder = body.Descendants<SdtBlock>();
this.SetPlaceholderTextValue(placeholder, "Company", WebApplication.Service.Properties.Settings.Default.CompanyName);
this.SetPlaceholderTextValue(placeholder, "Title", String.Format("Status Report for {0} to {1}", report.StartDate.ToShortDateString(),
report.ReportingInterval.EndDate.ToShortDateString()));
//this.SetPlaceholderTextValue(placeholder, "Subtitle", String.Format("for {0}", report.ReportingInterval.Project.Name));
this.SetPlaceholderTextValue(placeholder, "Author", report.TeamMember.User.Username);
this.SetPlaceholderTextValue(placeholder, "Date", String.Format("for {0}", DateTime.Today.ToShortDateString()));
}
private void SetPlaceholderTextValue(IEnumerable<SdtBlock> sdts, string alias, string value)
{
SdtContentBlock contentBlock = this.GetContentBlock(sdts, alias);
Text text = contentBlock.Descendants<Text>().First();
text.Text = value;
}
private SdtContentBlock GetContentBlock(IEnumerable<SdtBlock> sdts, string alias)
{
return sdts.First(sdt => sdt.Descendants<SdtAlias>().First().Val.Value == alias).SdtContentBlock;
}
public void Dispose()
{
this.document.Close();
}
}
公共类报告文档:IDisposable
{
私有内存流;
私有字处理文档;
私人文件部分;
公共字节[]文档数据
{
得到
{
this.document.ChangeDocumentType(WordprocessingDocumentType.MacroEnabledDocument);
byte[]documentData=this.stream.ToArray();
返回文档数据;
}
}
公共报告文件()
{
字节[]模板=DocumentTemplates.SingleReportTemplate;
this.stream=newmemoryStream();
stream.Write(template,0,template.Length);
this.document=WordprocessingDocument.Open(stream,true);
this.mainPart=document.MainDocumentPart;
}
公共作废报告(报告)
{
Body Body=mainPart.Document.Body;
var占位符=body.subjects();
SetPlaceholderTextValue(占位符,“公司”,WebApplication.Service.Properties.Settings.Default.CompanyName);
this.SetPlaceholderTextValue(占位符,“Title”,String.Format(“从{0}到{1}的状态报告”,Report.StartDate.ToShortDateString(),
report.ReportingInterval.EndDate.ToShortDateString());
//SetPlaceholderTextValue(占位符,“Subtitle”,String.Format(“for{0}”,report.ReportingInterval.Project.Name));
这个.SetPlaceholderTextValue(占位符,“作者”,report.TeamMember.User.Username);
这个.SetPlaceholderTextValue(占位符,“Date”,String.Format(“对于{0}”,DateTime.Today.ToShortDateString());
}
私有void SetPlaceholderTextValue(IEnumerable SDT、字符串别名、字符串值)
{
SdtContentBlock contentBlock=this.GetContentBlock(sdts,别名);
Text Text=contentBlock.subjects().First();
text.text=值;
}
私有SdtContentBlock GetContentBlock(IEnumerable SDT,字符串别名)
{
返回sdts.First(sdt=>sdt.subjects().First().Val.Value==alias.SdtContentBlock;
}
公共空间处置()
{
这个.document.Close();
}
}
因此,我创建了一个新文档,基于它通过内存流获得的模板,并希望在进行更改时将其写回内存流
最大的问题是,当我保存生成的字节数组时,数据docx文件已损坏:
\word中的document.xml称为document2.xml
document.xml.rels in.\word_rels称为document2.xml.rels,它包含
我希望你们中的一些人能够提供很好的解决方案
MFG SakeSushiBig将DocumentData属性更改为该属性,我认为它应该可以工作。重要的是在阅读memorystream之前关闭文档
public byte[] DocumentData
{
get
{
this.document.ChangeDocumentType(WordprocessingDocumentType.MacroEnabledDocument);
this.document.MainDocumentPart.Document.Save();
this.document.Close();
byte[] documentData = this.stream.ToArray();
return documentData;
}
}
请尝试CodePlex@上提供的项目。您的方法已经在那里实现,并提供了示例。由于您的回答,我注意到我没有关闭我的文档。