Reputation: 966
I want to offer users of my application to download a docx file which would contain dynamic content depending on their request. I prepared a template with header, otherwise the OpenXML creation is pain in the somewhere. Now I am having trouble with editing it and returning it as FileResult in my ASP MVC application.
My plan is to read a file to MemoryStream
and edit it as WordprocessingDocument
and then returning MemoryStream as Byte[]
.
I have two problems here:
WordprocessingDocument
directly from file without memory stream, I don't see a way to transform it to the shape FileResult()
wants.WordprocessingDocument
with empty MemoryStream
I can simply create content and return it as File
but I lack the previously prepared header with desired content. So, how to edit a .docx
template and return it as FileResult()
?
Upvotes: 2
Views: 2027
Reputation: 966
With the help from FortyTwo I managed to achieve my goal.
So the desired "workflow" is:
.docx
template (added headers or other things) to memoryFileResult
without saving the changes to templateSo here is the code:
public FileResult EditDOCXBody()
{
// Prepare file path
string file = "../WordTemplates/EmptyTemplate.docx";
String fullFilePath = HttpContext.ApplicationInstance.Server.MapPath(file);
// Copy file content to MemeoryStream via byte array
MemoryStream stream = new MemoryStream();
byte[] fileBytesArray = System.IO.File.ReadAllBytes(fullFilePath);
stream.Write(fileBytesArray, 0, fileBytesArray.Length); // copy file content to MemoryStream
stream.Position = 0;
// Edit word document content
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(stream, true))
{
MainDocumentPart mainPart = wordDoc.MainDocumentPart;
Body body = mainPart.Document.Body;
// add some text to body
body.Append(new Paragraph(
new Run(
new Text("Current time is: " + DateTime.Now.ToLongTimeString()))));
// Save changes to reflect on stream object
mainPart.Document.Save();
}
return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "servedFilename.docx");
}
Some important notes:
mainPart.Document.Save()
for changes to take effect on MemoryStream
.ToArray()
otherwise the returned file is corruptedUpvotes: 2
Reputation: 2649
This is how you go about creating a new spreadsheet document with MemoryStream
and then saving it to a Byte[]
Byte[] file;
using (MemoryStream mem = new MemoryStream())
{
using (SpreadsheetDocument spreadsheetDocument =
SpreadsheetDocument.Create(mem, SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.
AppendChild<Sheets>(new Sheets());
Sheet sheet = new Sheet()
{
Id = spreadsheetDocument.WorkbookPart.
GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "aStupidSheet"
};
sheets.Append(sheet);
workbookpart.Workbook.Save()
spreadsheetDocument.Close();
}
file = mem.ToArray();
}
Upvotes: 3