【问题标题】:How do I return a MemoryStream docx file MVC?如何返回 MemoryStream docx 文件 MVC?
【发布时间】:2013-01-15 19:45:21
【问题描述】:

我有一个 docx 文件,我想在进行编辑后返回它。我有以下代码...

object useFile = Server.MapPath("~/Documents/File.docx");
object saveFile = Server.MapPath("~/Documents/savedFile.docx");
MemoryStream newDoc = repo.ChangeFile(useFile, saveFile);
return File(newDoc.GetBuffer().ToArray(), "application/docx", Server.UrlEncode("NewFile.docx"));

该文件看起来不错,但我收到错误消息(“文件已损坏”和另一个说明“Word 发现无法读取的内容。如果您信任来源,请单击是”)。有什么想法吗?

提前致谢

编辑

这是我模型中的 ChangeFile...

    public MemoryStream ChangeFile(object useFile, object saveFile)
    {
        byte[] byteArray = File.ReadAllBytes(useFile.ToString());
        using (MemoryStream ms = new MemoryStream())
        {
            ms.Write(byteArray, 0, (int)byteArray.Length);
            using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(ms, true))
            {                    
                string documentText;
                using (StreamReader reader = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
                {
                    documentText = reader.ReadToEnd();
                }

                documentText = documentText.Replace("##date##", DateTime.Today.ToShortDateString());
                using (StreamWriter writer = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
                {
                    writer.Write(documentText);
                }
            }
            File.WriteAllBytes(saveFile.ToString(), ms.ToArray());
            return ms;
        }
    }

【问题讨论】:

  • 可以不用下载直接在Word中打开“~/Documents/savedFile.docx”文件吗?如果是,则问题是下载不完整/损坏。如果没有,您需要向我们展示repo.ChangeFile 内部发生的情况。
  • 从您的描述看来,您所做的更改似乎没有正确完成。
  • 请注意,有一个MemoryStream.ToArray() 方法,您不需要使用GetBuffer()
  • @0xA3 - 我可以直接打开文件。我认为下载不正确,但我不知道该怎么做。
  • @Lloyd - 我听取了您的建议并删除了 GetBuffer() 方法,它奏效了!你应该把它作为一个答案,这样我就可以回应并给你适当的信用。谢谢!

标签: c# asp.net-mvc asp.net-mvc-3 file-upload docx


【解决方案1】:

我使用FileStreamResult

var cd = new System.Net.Mime.ContentDisposition
    {
        FileName = fileName,

        // always prompt the user for downloading, set to true if you want 
        // the browser to try to show the file inline
        Inline = false,
    };
Response.AppendHeader("Content-Disposition", cd.ToString());

return new FileStreamResult(documentStream, "application/vnd.openxmlformats-officedocument.wordprocessingml.document");

【讨论】:

    【解决方案2】:

    不要使用MemoryStream.GetBuffer().ToArray(),使用MemoryStream.ToArray()

    GetBuffer() 的原因与用于创建内存流的数组有关,而不是与内存流中的实际数据有关。底层数组的大小实际上可能不同。

    隐藏在 MSDN 上:

    请注意,缓冲区包含可能未使用的已分配字节。 例如,如果将字符串“test”写入 MemoryStream 对象,GetBuffer返回的缓冲区长度是256,不是 4,有 252 个字节未使用。要仅获取缓冲区中的数据,请使用 ToArray 方法;但是, ToArray 在 记忆。

    【讨论】:

    • 您的回答解决了我的错误:我使用了 GetBuffer 并且最后一行得到了一大行 NULL。用 ToArray 替换 GetBuffer 解决了它!谢谢!
    猜你喜欢
    • 1970-01-01
    • 2011-05-06
    • 2019-04-17
    • 1970-01-01
    • 2021-10-29
    • 2012-01-15
    • 1970-01-01
    • 2016-04-20
    • 2014-08-25
    相关资源
    最近更新 更多