I am trying to use the amazing DocX library on codeplex to create a word document.
when the user clicks a button, the document is created and I want to be able to send it to the user immediately via response.. I am doing something similar to this now:
Edited code based on suggestions
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();
}
I have tried a few variations of this.. but I am not able to achieve what I want.. Looking at this answer I can possibly save the document on the server and open with io stream.. but I want to avoid that extra step (and then I need to delete the file too)
I don't see the point of creating a file for few milli seconds.. there has to be a way to save the contents and send them to response stream.. right?
How'd I go about it? thanks..
EDIT: my current code either throws up cannot open file (Access denied) error If I am using file stream, OR downloads an empty document file without any content (sometimes, type of response is written to document)
System.IO.MemoryStream
as it's content..
Okay, here is the final working solution:
For some reason, DocX library doesn't want to save to Response.OutputStream
directly, so I had to save it to memory stream and write the memory stream to response, like Neil & Daniel suggested. Here's what worked for me:
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();
This might be a bit late, but I found a way to get this working with 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;
}
}
The important bit is setting the Position of the memorystream back to 0, otherwise it appeared to be at the end, and the file was returning empty.