I'm trying to have a website export a .xlsm file and I can't seem to find anything that helps. Here's a simple example I'm using to test building a .xlsx file (which works).
#using OfficeOpenXml;
<html>
<body>
<div id="page-wrapper">
#{
// Change file extension to xlsm to test
string fileExtension = "xlsm";
ExcelPackage p = new ExcelPackage();
p.Workbook.Worksheets.Add("Worksheet Name");
int LatestWorksheetNumber = p.Workbook.Worksheets.Count;
ExcelWorksheet ws = p.Workbook.Worksheets[LatestWorksheetNumber];
ws.Cells[1, 1].Value = "Test";
//Generate A File
Byte[] bin = p.GetAsByteArray();
string filename = "filename";
try
{
//Download the file as an attachment
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.Cookies.Clear();
string ContentType = "";
if (fileExtension == "xlsx")
{
ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
}
else
{
ContentType = "application/vnd.ms-excel.sheet.macroEnabled.12";
}
Response.GetType();
Response.ContentType = ContentType;
Response.AddHeader("content-disposition", "attachment; filename=" + filename + "." + fileExtension);
Response.BinaryWrite(bin);
Response.End();
<p>File Created</p>
}
catch (Exception e)
{
<p>#e.Message</p>
}
}
</div>
</body>
</html>
After changing the file extension to .xlsm the file is generated but when I try to open the file in Excel I get an error saying that the extension isn't correct. I thought the only thing I would have to change would be the content type header but that's obviously not the issue. What else am I missing??? Any guidance would be appreciated!
Xiaoy312 nailed the issue! Adding p.Workbook.CreateVBAProject(); before Byte[] bin = p.GetAsByteArray(); solved my issue! Everything else stayed the same but Excel will actually open the files now! Here's my final code for anyone who has the same issue:
#using OfficeOpenXml;
<html>
<body>
<div id="page-wrapper">
#{
// Change file extension to xlsm to test
string FileExtension = "xlsm";
ExcelPackage p = new ExcelPackage();
p.Workbook.Worksheets.Add("Worksheet Name");
int LatestWorksheetNumber = p.Workbook.Worksheets.Count;
ExcelWorksheet ws = p.Workbook.Worksheets[LatestWorksheetNumber];
ws.Cells[1, 1].Value = "Test";
p.Workbook.CreateVBAProject();
//Generate A File
Byte[] bin = p.GetAsByteArray();
string filename = "filename";
try
{
//Download the file as an attachment
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.Cookies.Clear();
string ContentType = "";
if (FileExtension == "xlsx")
{
ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
}
else
{
ContentType = "application/vnd.ms-excel.sheet.macroEnabled.12";
}
Response.GetType();
Response.ContentType = ContentType;
Response.AddHeader("content-disposition", "attachment; filename=" + filename + "." + FileExtension);
Response.BinaryWrite(bin);
Response.End();
<p>File Created</p>
}
catch (Exception e)
{
<p>#e.Message</p>
}
}
</div>
</body>
</html>
Related
I'm getting this error in ExcelPackage.GetAsByteArray() while exporting excel. I have tried everything as UTF-8 encoding etc but nothing works.
Below is my code
public void function Export()
{
ExcelPackage package = ExportUtil.GetMacroEnabledExtract(ds, extractName, "Comments");
Response.Clear();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition", "attachment;filename=\"" + ExportUtil.getFileName(extractName, ".xlsm") + "\"");
Response.BinaryWrite(package.GetAsByteArray());
Response.End();
}
export function
public static ExcelPackage GetMacroEnabledExtract(DataSet ds, string extractName, string dataSheetName)
{
string appDataPath = HostingEnvironment.MapPath(#"~/App_Data");
string filePath = Path.Combine(appDataPath, "MacroTemplate.xlsm");
FileInfo templateFile = new FileInfo(filePath);
ExcelPackage package = new ExcelPackage(templateFile, false);
string fileName = getFileName(extractName, ".xlsm");
createDataWorkSheetMacroEnabled(package, ds.Tables[0], dataSheetName, templateFile); //Sheet 1
return package;
}
private static void createDataWorkSheetMacroEnabled(ExcelPackage package, DataTable table, string worksheetName, FileInfo file)
{
ExcelWorksheet wsData = package.Workbook.Worksheets[1];
wsData.Cells["A1"].LoadFromDataTable(table, true);
ExcelTextFormat format = new ExcelTextFormat();
format.Encoding = new UTF8Encoding();
wsData.Cells.LoadFromText(file, format);
}
I am trying to generate a csv with UTF8 encoding with c#, using ExcelPackage (). Excel is identifying the file as .xlsx and not UTF8. My code:
using (ExcelPackage package = new ExcelPackage())
{
ExcelWorksheet ws = package.Workbook.Worksheets.Add("myName");
int y = 1;
foreach (IDictionary<string, string> elemento in losDatos)
{
ws.Cells["A" + y].Value = "+ DisposiciĆ³n de contacto";
ws.Cells["B" + y].Value = "Llamada detallada";
...
...
ws.Cells["AL" + y].Value = "1";
y++;
}
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("Content-Disposition", "attachment;filename=myName" + DateTime.Now.ToString("yyyyMMdd_HHmm") + ".csv");
Response.BinaryWrite(package.GetAsByteArray());
Response.End();
}
I have tried some changes, only in the Response piece, and now the csv recognizes me, but the characters are strangers:
Response.Clear();
Response.ContentType = "application/csv";
Response.AddHeader("Content-Disposition", "attachment;filename=myName" + DateTime.Now.ToString("yyyyMMdd_HHmm") + ".csv");
Response.BinaryWrite(Encoding.UTF8.GetPreamble());
Response.BinaryWrite(package.GetAsByteArray());
Response.End();
Replace
Response.ContentType = "application/csv";
Response.AddHeader("Content-Disposition", "attachment;filename=myName" + DateTime.Now.ToString("yyyyMMdd_HHmm") + ".csv");
Response.BinaryWrite(Encoding.UTF8.GetPreamble());
with
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("Content-Disposition", "attachment;filename=myName" + DateTime.Now.ToString("yyyyMMdd_HHmm") + ".xlsx");
and you are done.
If you want a CSV, use a different package but then do consider adding charset to the Content-Type header. If Open XML is not your thing, then OpenDocument Spreadsheet (.odt, LibreOffice) would be equally better than CSV.
string fileName = "test" + DateTime.Now.ToShortDateString();
using (package = new ExcelPackage(newFile, "file"))
{
generateReport();//this function generates a worksheet
package.Workbook.Properties.Title = #"Title of project";
package.Workbook.Properties.Author = "Sri";
package.Workbook.Properties.Subject = #"Report";
byte[] rawData = package.GetAsByteArray();
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.AddHeader("content-disposition", "attachment; filename=" + fileName + ".xlsx");
Response.BinaryWrite(rawData);
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.Flush();
Response.End();
Hi,when i try to export datatable to excel ,columns which has date appears as numbers in the excel file.When i further check these numbers are DATEVALUE(date)(this function is used in excel) results of excel.
I am using this code to download a image i.e. I am storing Image name with extension in database and getting it here.
this code throws no error but doesn't download anything. why ?
try {
if (e.CommandName == "Download")
{
string ImgPath = Convert.ToString(r["Attachment"]);
//string ImgName = r["ComplaintDetailID"].ToString() + "-" + r["LetterNo"].ToString() + "-" + DateTime.Now.ToString("ddMMyyyyhhmmss");
//string filePath = ImgName + ".jpg";
string fullFilePath = Server.MapPath("~/SiteImages/CMS/" + ImgPath);
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.AddHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(fullFilePath));
Response.ContentType = ContentType;
Response.TransmitFile(fullFilePath); //downloads file
Response.Flush();
//FileInfo file = new FileInfo(fullFilePath);
//file.Delete(); //deletes file after downloading
}
}
catch (Exception ex)
{
ResultLabel.ResultLabelAttributes(ex.Message, ProjectUserControls.Enums.ResultLabel_Color.Red);
}
finally
{
ResultPanel.Controls.Add(ResultLabel);
}
Update:
i tried this but doesn't work.
if (e.CommandName == "Download")
{
string ImgPath = Convert.ToString(r["Attachment"]);
//string ImgName = r["ComplaintDetailID"].ToString() + "-" + r["LetterNo"].ToString() + "-" + DateTime.Now.ToString("ddMMyyyyhhmmss");
//string filePath = ImgName + ".jpg";
MemoryStream m = new MemoryStream();
File.OpenRead(ImgPath).CopyTo(m);
m.WriteTo(Response.OutputStream);
string fullFilePath = Server.MapPath("~/SiteImages/CMS/" + ImgPath);
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.AddHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(fullFilePath));
Response.ContentType = ContentType;
Response.TransmitFile(fullFilePath); //downloads file
Response.Flush();
//FileInfo file = new FileInfo(fullFilePath);
//file.Delete(); //deletes file after downloading
}
Create a Stream using following code
MemoryStream m = new MemoryStream();
File.OpenRead(ImgPath ).CopyTo(m);
m.WriteTo(Response.OutputStream);
You're on the right track using TransmitFile. Check this line:
Response.ContentType = ContentType;
It looks like you're setting the ContentType to the page's default.
Try specifying it explicitly:
Response.ContentType = "image/jpeg";
I have asked this before but am still having difficulties in initiating the file download.
var fileName = "ExcelData.xlsx";
var file = new FileInfo(fileName);
using (var package = new OfficeOpenXml.ExcelPackage(file))
{
var worksheet = package.Workbook.Worksheets.FirstOrDefault(x => x.Name == "Employee Data");
if (package.Workbook.Worksheets.FirstOrDefault(x => x.Name == "Employee Data") == null)
{
worksheet = package.Workbook.Worksheets.Add("Employee Data");
}
else
{
package.Workbook.Worksheets.Delete(1);
worksheet = package.Workbook.Worksheets.Add("Employee Data");
}
worksheet.Cells[1, 1].Value = "Date start";
worksheet.Cells[1, 2].Value = "Name";
var rowCounter = 2;
foreach (var v in users)
{
string dt = v.DateAdded.ToString();
worksheet.Cells[rowCounter, 1].Value = dt;
worksheet.Cells[rowCounter, 2].Value = v.Name;
rowCounter++;
}
package.Workbook.Properties.Title = "Employee Data";
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.Clear();
response.Buffer = true;
response.Charset = "";
response.ContentType = "application/vnd.openxmlformats- officedocument.spreadsheetml.sheet";
response.AddHeader("content-disposition", "attachment;filename=ExcelData.xlsx");
response.BinaryWrite(package.GetAsByteArray());
}
As it is at the moment no errors occur but the download is also not triggered. How do I trigger the download so that the generated file is saved to a default download folder
Why don't you return a FileContentResult?
Since the Excel library you are using can return the sheet as a byte array, this could work for you.
In your controller, you can just return the FileContentResult like this:
return File(package.GetAsByteArray(), "application/xlsx", "YourReportName.xlsx");
So you can remove this block from you code:
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.Clear();
response.Buffer = true;
response.Charset = "";
response.ContentType = "application/vnd.openxmlformats- officedocument.spreadsheetml.sheet";
response.AddHeader("content-disposition", "attachment;filename=ExcelData.xlsx");
response.BinaryWrite(package.GetAsByteArray());
and just return the File as shown above.
Just note you have to add a using statement to your controller for System.Web.Mvc.
Try after your code:
Response.Flush();
Response.Close();
Response.End();
It immediately outputs the result.