2012-04-07 191 views
3

儘管我是Open-XML世界的新手,但我已經遇到了一些使用它的麻煩/問題。他們中的大多數很容易解決,但我不能圍繞這一得到:Open-XML保存Word文檔產生損壞的文件

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(); 
    } 
} 

所以我創建一個新的文件,在此基礎上獲得通過內存流模板,並希望將其寫回內存當進行更改時流。

最大的問題是,當我保存生成的字節數組數據的docx文件損壞:

的document.xml中在\詞稱爲document2.xml 所述的document.xml.rels \。 word_rels被稱爲document2.xml.rels,它包含 我希望你們中的一些人能爲它提供良好的解決方案。

MFG SakeSushiBig

+0

嘗試使用CodePlex @ http://worddocgenerator.codeplex.com/上的項目。您的方法已經在那裏實施,並提供樣品。 – 2012-04-07 16:37:46

回答

6

更改您的DocumentData屬性這一點,我認爲它應該工作。重要的是在讀取內存流之前關閉文檔。

public byte[] DocumentData 
    { 
     get 
     { 
      this.document.ChangeDocumentType(WordprocessingDocumentType.MacroEnabledDocument); 
      this.document.MainDocumentPart.Document.Save(); 
      this.document.Close();    
      byte[] documentData = this.stream.ToArray(); 
      return documentData; 
     } 
    } 
+0

感謝您的回答,我注意到我沒有「關閉」我的文檔。 – Anarion 2016-12-29 07:07:34