c# - Open-XML 保存 word 文档产生损坏的文件

标签 c# ms-word ms-office openxml

虽然我是 Open-XML 世界的新手,但我在使用它时已经遇到了一些麻烦/问题。其中大部分很容易解决,但我无法解决这个问题:

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 文件已损坏:

.\word中的document.xml叫做document2.xml .\word_rels 中的 document.xml.rels 称为 document2.xml.rels,它包含 我希望你们中的一些人能够为此提供好的解决方案。

MFG清酒寿司大

最佳答案

将您的 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;
        }
    }

关于c# - Open-XML 保存 word 文档产生损坏的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10050628/

相关文章:

c# - 如何将FTP文件移动到C#中的另一个目录?

c# - 需要使用 select 的 Linq 查询才能从列表中获取特定属性

azure - 用于在 Azure 存储中编辑 MS Word 文档的选项

ms-access - 以编程方式添加引用

sql - Access 将行连接成单行 : extra conditions needed

c# - 如何更改查询字符串参数的值?

c# - 如何使用 C# 在我的 Windows 窗体应用程序中嵌入 vlc

.net - 使用 itextsharp 阅读 PDF,其中 PDF 语言为非英语

vba - 为什么 .Font.Reset 在查找/替换 VBA 宏中不起作用?

plugins - 卸载 VSTO 插件