While creating an Excel document at runtime I get the following error:
Excel found unreadable content in 'Filename.xlsx'. Do you want to
recover the content of this workbook? If you trust the source of this
workbook, Click yes.
I have seen many posts regarding this on stack overflow but they have not helped me in this situation.
Below is my C# code which (attempts to) create the excel file:
var workbook = new XLWorkbook();
System.Data.DataTable Table = new System.Data.DataTable();
string AdvId = GlobalEntityID + "-" + AyId + "-" + QtrID;
var CSRExpenditureData = objCsrExp.GetCSRExpendituresFromSP(AdvId); //Get data in list from sp
Table = ListToDataTable(CSRExpenditureData); //Convert list to datatable
Table.Columns.Remove("ID"); //Remove extra columns
Table.Columns.Remove("IsActive"); //Remove extra columns
Table.Columns.Remove("IsDefault"); //Remove extra columns
Table.Columns.Remove("IsSubmit"); //Remove extra columns
if (Table.Columns.Count > 0)
{
var ws = workbook.Worksheets.Add(Table, ReportName);
}
workbook.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
workbook.Style.Font.Bold = true;
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment;filename=" + ReportName + ".xlsx");
using (MemoryStream MyMemoryStream = new MemoryStream())
{
workbook.SaveAs(MyMemoryStream);
MyMemoryStream.WriteTo(Response.OutputStream);
}
Note : Please don't mark this as duplicate because I have tried other posts as well
Related
I want to create an hyperlink to a cell in Excel sheet while I am doing export to cell in C# MVC 5, I am using grid view to export to Excel.
I have used anchor tag to create link, when the files gets exported it read that field as string.
What is the other way to achieve this?
Below is what I have tried:
var result = from cssd in csdvm.FillControlStatusDetails.AsEnumerable()
select new
{
link = "<a href='www.google.com'> Link</a>
}
GridView gvExport = new GridView();
gvExport.AutoGenerateColumns = false;
BoundField nameColumn = new BoundField();
nameColumn.DataField = "link";
nameColumn.HeaderText = "Link";
gvExport.Columns.Add(nameColumn);
gvExport.DataSource = result.AsQueryable().ToList();
gvExport.DataBind();
gen.CreateExportHeaderRow(gvExport, "Control Status - Details");
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment; filename=ControlStatusDeatils-" + DateTime.Now.ToFileTimeUtc() + ".xls");
Response.ContentType = "application/vnd.xls";
Response.Charset = "";
System.IO.StringWriter sw = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htw = new System.Web.UI.HtmlTextWriter(sw);
gvExport.RenderControl(htw);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
Thank you i found the way out..i used a for loop to add the link below is what is did
for (int i = 0; i < gvExport.Rows.Count; i++)
var link = "<a href='" + gvExport.Rows[i].Cells[9].Text + "'>" + gvExport.Rows[i].Cells[10].Text+ "</a>" + "<br/>";
}
gvExport.Rows[i].Cells[9].Text = MvcHtmlString.Create(link).ToHtmlString();
using above code i am able to give an hyper link to an Excel cell while i am doing export to excel
My below code is working well except for one slight issue. When I open the excel sheet, the column headers are pulling directly from the code below I.E.data.FleetNumber displays as FleetNumber for the column header.
Is it possible to overwrite this? E.G I want it to display Fleet No.
I've done a lot of searching but I cant find an answer. Any help is appreciated.
public void ExportToBeDoneVehiclesToExcel()
{
int count = 10;
var grid = new System.Web.UI.WebControls.GridView();
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
var list = vehicleBusinessLogic.GetToBeDoneVehicles(count);
grid.DataSource = from data in list
select new
{
data.RegistrationID,
data.FleetNumber,
data.VIN,
data.LocationDescription,
data.ServiceDescription,
data.NextInspectionDueDate
};
grid.DataBind();
Response.ClearContent();
Response.AddHeader("content-disposition", "attachment; filename=Exported_ToBeDoneVehicles.xls");
Response.ContentType = "application/excel";
grid.RenderControl(htw);
Response.Write(sw.ToString());
Response.End();
}
i can't test this but it seems logical to me
try specifying the variables names in the list
grid.DataSource = from data in list
select new
{
Reg = data.RegistrationID,
FleetNumber = data.FleetNumber,
VIN = data.VIN,
LocationDescription = data.LocationDescription,
ServiceDescription = data.ServiceDescription,
NextInspectionDueDate = data.NextInspectionDueDate
};
Haven't found any good solution to export a GridView to Excel with following options :
Page orientation set to Landscape
Margins Normal
All columns fit to one page
Existing code to export to Excel is as follows
private void ExportToExcel(GridView grdGridView)
{
DataTable dt = Whatever();
grdGridView.AllowPaging = false;
grdGridView.Columns[13].Visible = false;
grdGridView.DataSource = dt;
grdGridView.DataBind();
string attachment = "attachment; filename=ExcelSheet1.xls";
Response.ClearContent();
Response.AddHeader("content-disposition", attachment);
Response.ContentType = "application/ms-excel";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
HtmlForm frm = new HtmlForm(); // Create a form to contain the grid
grdGridView.Parent.Controls.Add(frm);
frm.Attributes["runat"] = "server";
frm.Controls.Add(grdGridView);
frm.RenderControl(htw);
Response.Write(sw.ToString());
Response.End();
}
}
What could be the best possible way to export to Excel in order to achieve all of this? Do I need to use some library or some other tool like report viewer? Is it possible or not?
Found the solution
Download epplus library.
using OfficeOpenXml;
private void ExportToExcel()
{
using (ExcelPackage objExcelPackage = new ExcelPackage())
{
//Create the worksheet
ExcelWorksheet objWorksheet = objExcelPackage.Workbook.Worksheets.Add("ExcelSheet1");
DataTable dtQuoteComparison = dt //Load the datatable into the sheet, starting from cell A1. Print the column names on row 1
objWorksheet.Cells["A1"].LoadFromDataTable(dt, true);
var start = objWorksheet.Dimension.Start;
var end = objWorksheet.Dimension.End;
for (int row = start.Row+1; row <= end.Row; row++) //iterate through rows
{
objWorksheet.Cells[rowStart, colStart, rowEnd,colEnd].WhateverProperty=value;
}
objWorksheet.PrinterSettings.Orientation = eOrientation.Landscape;
objWorksheet.PrinterSettings.FitToWidth = 1;
//Write it back to the client
if (System.IO.File.Exists(filepath))
System.IO.File.Delete(filepath);
//Create excel file on physical disk
FileStream objFileStrm = System.IO.File.Create(filepath);
objFileStrm.Close();
//Write content to excel file
System.IO.File.WriteAllBytes(filepath,objExcelPackage.GetAsByteArray());
}
}
Now the problem I am facing is that All columns fit to one page is not working even after setting
objWorksheet.PrinterSettings.FitToWidth = 1;
Given below is my code.. I have Excel template that contains 2 or three sheet. when I am performing and saving data on all excel its getting successful but if I am working on only one excel sheet it throws exception on xlPackage.Save();
HOW to save on only one sheet of Excel
String filePath = string.Format(ConfigurationManager.AppSettings["IcxFileFormatPath"]);
filePath += #"\ARK_New_FromDeviceSettings.xlsx";
String Template = string.Format(ConfigurationManager.AppSettings["IcxFileFormatTempPath"]);
FileInfo newFile = new FileInfo(filePath);
FileInfo UITemplate = new FileInfo(Template + #"\ARK_New_FromDeviceSettings.xlsx");
using (ExcelPackage xlPackage = new ExcelPackage(newFile, UITemplate))
{
ExcelWorksheet systemWorksheet = xlPackage.Workbook.Worksheets["System Details"];
if (systemWorksheet != null)
{
const int startRow = 2;
int row = startRow;
// DataTable dt
foreach (var systemDetailList in systemDetail)
{
if (row > startRow)
systemWorksheet.InsertRow(row);
systemWorksheet.Cell(row, 1).Value = Convert.ToString(systemDetailList.ModbusTCPIDofDCUDevice);
systemWorksheet.Cell(row, 2).Value = systemDetailList.DCUSerialNumber;
}
}
xlPackage.Save();
}
// HttpContext context = HttpContext.Current;
Response.Clear();
Response.Clear();
Response.ContentType = "application/ms-excel";
Response.AppendHeader("Content-Disposition", "attachment;filename=UIRateTemplate.xlsx");
Response.WriteFile(filePath);
Response.Flush();
Response.End();
Since you don't do anything other than save the ExcelPackage if there is no "System Details" worksheet, why don't you move the line "xlPackage.Save()" one line up, before that close brace? It will no longer save, but you aren't making any changes anyhow, and you'll eliminate the NullReferenceException.
I have the following method that eventually creates a CSV file and returns the file as a response to a client request.
How can I change the column width to autofit and have alternate coloring of rows?
public static void ExportToCSV(DataTable dt, HttpResponseBase response, string filename)
{
response.AddHeader("content-disposition", "attachment; filename=" + filename);
response.ClearContent();
response.ContentType = "application/vnd.ms-excel";
response.Charset = "UTF-8";
response.ContentEncoding = System.Text.Encoding.Unicode;
response.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble());
string tab = "";
foreach (DataColumn dc in dt.Columns)
{
if (!dc.ColumnName.StartsWith("_"))
{
response.Write(tab + dc.ColumnName);
tab = "\t";
}
}
response.Write("\n");
int i;
foreach (DataRow dr in dt.Rows)
{
tab = "";
for (i = 0; i < dt.Columns.Count; i++)
{
if (!dr.Table.Columns[i].ColumnName.StartsWith("_"))
{
response.Write(Utils.StripHTML(tab + dr[i].ToString().Replace("\n", " ").Replace("\t", " ")));
tab = "\t";
}
}
response.Write("\n");
}
response.End();
}
CSV file is just plain text where values are separated by an agreed separator (usually comma, hence the name, in your case it's TAB character).
Excel has a support for CSV files in such way it represent every value in separate column. This is only visual representation but the file has no actual columns, and cannot contain any form of formatting.
You'd need to change the format of the file to Excel format, and create it that way. You could use Excel interop or writing it as an excel XML file. I'd recommend second option. For a working example of Excel XML you can check this CodeProject example.
You are currently creating a delimited text file.
As the file is a normal text file, it can not have any formatting applied.
Your requirements are to generate an excel file with formatting and certain width, as such this can only be achieved by producing an excel file directly.
This can be done using interop or by outputting the xml required, but some kind of excel library is probably easier to implement without worrying about the details. I personally prefer EPPlus. It is a useful library for creating Excel spreadsheet for excel 2007 onwards. You can install the library using nugget or via a download from the website.
The following gives a quick overview of how to achieve this.
public static void ExportToCSV(DataTable dt, HttpResponseBase response, string filename)
{
response.AddHeader("content-disposition", "attachment; filename=" + filename);
response.ClearContent();
response.ContentType = "application/vnd.ms-excel";
response.Charset = "UTF-8";
response.ContentEncoding = System.Text.Encoding.Unicode;
response.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble());
ExcelPackage package = new ExcelPackage();
package.Workbook.Properties.Comments = "Demo Excel Generation";
package.Workbook.Worksheets.Add("DemoSheet");
ExcelWorksheet sheet = package.Workbook.Worksheets["DemoSheet"];
bool altColour = false;
for (int i = 1; i < 10; i++)
{
for (int j = 1; j < 10; j++)
{
sheet.Cells[i, j].Value = string.Format("{0} - {1}", i, j);
sheet.Row(j).Style.Fill.PatternType = ExcelFillStyle.Solid;
sheet.Row(j).Style.Fill.BackgroundColor.SetColor(altColour ? Color.Gold : Color.Goldenrod);
altColour = !altColour;
}
sheet.Column(i).AutoFit(5f); // Set minimum width to 5 points
}
//package.File = new System.IO.FileInfo(#"C:\test.xlsx");
//package.Save();
package.SaveAs(response.OutputStream);
Response.End();
}
Another library is ClosedXML which has (in my opinion) a nicer syntax than other possibilities by allowing to chain methods. For example:
XLWorkbook workbook = new XLWorkbook("test.xlsx");
IXLWorksheet worksheet = workbook.AddWorksheet("Sheet1");
worksheet.Cell(1, 1).SetValue("Test").Style.Font.SetBold(true);
worksheet.AdjustToContent(); // this changes the column width to fit the content
workbook.Save();