将docX创建的文档保存到响应中并将其发送给用户进行下载

时间:2012-01-24 14:58:03

标签: c# c#-4.0 docx

我正在尝试使用惊人的DocX library on codeplex创建一个word文档。

当用户点击按钮时,文档已创建,我希望能够通过响应立即将其发送给用户。我现在正在做类似的事情:

根据建议编辑代码

using (DocX Report = DocX.Create(string.Format("Report-{0}.doc", DateTime.Now.Ticks)))
{
    Paragraph p = Report.InsertParagraph();
    p.Append("Title").FontSize(30).Bold()
    .Append("Sub title").FontSize(28)
        .AppendLine()
        .Append(DateTime.Now.Date) 
    ;

    MemoryStream ms = new MemoryStream();
    Report.SaveAs(ms);


    Response.Clear();
    Response.AddHeader("content-disposition", "attachment; filename=\"" + fileName + ".docx\"");
    Response.ContentType = "application/msword";

    Response.Write(ms);
    Response.End();
}

我尝试了一些这方面的变化..但我无法达到我想要的效果。Looking at this answer我可以将文档保存在服务器上并使用io流打开..但我想要避免那个额外的步骤(然后我也需要删除文件)

我没有看到创建一个文件几毫秒的重点..必须有一种方法来保存内容并将它们发送到响应流..对吧?

我是怎么做到的? 感谢..

编辑:我当前的代码或者抛出无法打开文件(拒绝访问)错误如果我正在使用文件流,或者下载没有任何内容的空文档文件(有时,响应的类型写入文档)

<小时/> 此代码为我提供了一个包含System.IO.MemoryStream内容的MS Word文档。


好的,这是最终的解决方案:

出于某种原因,DocX库并不想直接保存到Response.OutputStream,因此我必须将其保存到内存流并将内存流写入响应,如Neil&amp; Daniel建议。这对我有用:

MemoryStream ms = new MemoryStream()
Report.SaveAs(ms);

Response.Clear();
Response.AddHeader("content-disposition", "attachment; filename=\"" + fileName + ".doc\");
Response.ContentType = "application/msword";

ms.WriteTo(Response.OutputStream);
Response.End();

4 个答案:

答案 0 :(得分:5)

这可能有点晚了,但我找到了一种方法来使用FileStreamResult:

    public FileStreamResult DownloadDocument()
    {
        using (DocX document = DocX.Create(@"Test.docx"))
        {
            // Insert a new Paragraphs.
            Paragraph p = document.InsertParagraph();

            p.Append("I am ").Append("bold").Bold()
            .Append(" and I am ")
            .Append("italic").Italic().Append(".")
            .AppendLine("I am ")
            .Append("Arial Black")
            .Font(new FontFamily("Arial Black"))
            .Append(" and I am not.")
            .AppendLine("I am ")
            .Append("BLUE").Color(Color.Blue)
            .Append(" and I am")
            .Append("Red").Color(Color.Red).Append(".");

            var ms = new MemoryStream();
            document.SaveAs(ms);
            ms.Position = 0;

            var file = new FileStreamResult(ms, "application/vnd.openxmlformats-officedocument.wordprocessingml.document")
            {
                FileDownloadName = string.Format("test_{0}.docx", DateTime.Now.ToString("ddMMyyyyHHmmss"))
            };

            return file;

        }
    }

重要的一点是将内存流的位置设置为0,否则它似乎在最后,文件返回空。

答案 1 :(得分:2)

尝试使用MemoryStream代替FileStream

您当前的代码看起来非常错误:

您要将报告保存到当前回复的OutputStream,然后清除回复(!)

答案 2 :(得分:2)

执行Report.SaveAs(response.OutputStream);时 - 它已将文件内容写入输出流。您无需执行Response.Write(response.OutputStream);

所以你的代码应该是这样的:

...

Report.SaveAs(response.OutputStream);
Response.AddHeader("content-disposition", "attachment; filename=\"" + fileName + ".doc\"");
Response.ContentType = "application/msword";

答案 3 :(得分:1)

我认为你有一些事情要回到前面而且很困惑。

首先,清除输出,然后添加标题,然后写出内容。

Response.Clear(); 
Response.AddHeader("content-disposition", "attachment; filename=\"" + fileName + ".doc\""); 
Response.ContentType = "application/msword"; 

// This writes the document to the output stream.
Report.SaveAs(response.OutputStream); 

Response.End(); 

此外,如果您的文件是docx格式文件,请将.docx而不是.doc附加到您的文件名。