I got a problem when export an arabic work to excel from c# code behind:
the code I use for :
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
string attachment = "attachment; filename=Employee.xls";
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.Charset = "UTF-8";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
HttpContext.Current.Response.AddHeader("content-disposition", attachment);
HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
Response.Write("السبت");// this word mean Saturday in arabic
Response.End();
Application.UnLock();
but after I open the excel file its look like :
why the word look like this and how to fix it ?
and if you see in the second row the size of the word didn't fit with the size of the cell how to do it ?
another question : how to color the background of the cell from c# code behind and how to combine cell ?
thx any way
I took your example rewrote it on my end just now tested it and everything works fine
I wonder if you are experiencing a Culture issue
keep in mind the filename I am assigning on my end and passing it to a Method
public static void ExportToExcel(DataTable table, string fileName)
{
HttpContext context = HttpContext.Current;
context.Response.Clear();
context.Response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1254");
context.Response.Charset = "windows-1254"; //ISO-8859-13 ISO-8859-9 windows-1254
//Begin Table
context.Response.Write("<table><tr>");
//Write Header
foreach (DataColumn column in table.Columns)
{
context.Response.Write("<th>" + column.ColumnName + "</th>");
}
context.Response.Write("</tr>");
//Write Data
foreach (DataRow row in table.Rows)
{
context.Response.Write("<tr>");
for (int i = 0; i < table.Columns.Count; i++)
{
context.Response.Write("<td>" + row[i].ToString().Replace(",", string.Empty) + "</td>");
}
context.Response.Write("</tr>");
}
//End Table
context.Response.Write("</table>");
context.Response.ContentType = "application/vnd.ms-excel";
context.Response.AppendHeader("content-disposition", string.Format("attachment;filename={0}.xls", fileName));
context.Response.Flush();
context.Response.End();
}
use 1256 rather than 1254 it's working good :)
HttpContext context = HttpContext.Current;
context.Response.Clear();
context.Response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1256");
context.Response.Charset = "windows-1256"; //ISO-8859-13 ISO-8859-9 windows-1256
Related
Within my code I have an asp repeater and I wish to allow users to export the data from this to a csv file. Exporting to a csv works fine but when I wish to show a dialog box for users to choose where to save to nothing happens. I have went through several different solutions that apparently work but when I run them in my code nothing happens and I can not figure out why. This is my code at the moment:
protected void exportCSV_Click(object sender, EventArgs e)
{
try
{
string FilePath = Server.MapPath("~") + "\\test.csv";
StringBuilder columnbind = new StringBuilder();
foreach (Control item in rpt_bookings.Items)
{
Literal row1 = (Literal)item.FindControl("ltl_bookingemail");
Literal row2 = (Literal)item.FindControl("ltl_bookingphone");
Literal row3 = (Literal)item.FindControl("ltl_bookingcost");
string fullRow = row1.Text.ToString() + "," + row2.Text.ToString() + "," + row3.Text.ToString();
columnbind.Append(fullRow);
columnbind.Append("\r\n");
}
//// Creates the file on server
File.WriteAllText(FilePath, columnbind.ToString());
string FileName = "test.csv";
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "text/csv";
response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + ";");
response.TransmitFile(FilePath);
response.Flush();
response.End();
//// Deletes the file on server
File.Delete(FilePath);
//response.End();
lblmsg.Text = "";
}
catch (Exception ex)
{
Console.Write(ex);
Debug.Write(ex);
lblmsg.Text = ex.Message;
lblmsg.Style.Add("color", "#c73939");
}
}
The csv is correctly created but nothing happens with the response. The code executes but nothing comes up on the screen at all. According to several other questions along the same lines this is the solution.
Try the following changes:
response.ContentType = "application/octet-stream";
response.AppendHeader("Content-Disposition","attachment; filename=" + Filename + ";");
response.TransmitFile( FilePath );
response.End();
Don't delete the file in the next line but in the finally block instead:
catch (Exception ex)
{
[..]
}
finally
{
File.Delete(FilePath);
}
I tried to export the dataset which have 2 tables to the excel sheet, unfortunately I can't.
I have code to export data table to excel. So instead of dataset, I called the ExportToExcel function which I have in my code to export datatable to excel 4 times. But once it created the first sheet, it stops the control flow. Control doesn't call the second function
ExportToExcel(getReports.Tables[1], "ConsumerBookedSlots");
Here is the code:
public ActionResult GetCuratorsAvailability(string availabilitydate)
{
string fromDate = "";
string endDate = "";
if (availabilitydate != "")
{
fromDate = availabilitydate.Split('-')[0];
endDate = availabilitydate.Split('-')[1];
if (DateTime.Parse(endDate) >= DateTime.Parse(fromDate))
{
DataSet getReports = AdminBLL.GetCuratorsAvailability(fromDate, endDate);
ExportToExcel(getReports.Tables[0], "CuratorsAvailableSlots");
ExportToExcel(getReports.Tables[1], "ConsumerBookedSlots");
}
}
return View("Reports");
}
public void ExportToExcel(DataTable dt, string FileName)
{
if (dt.Rows.Count > 0)
{
if (System.Web.HttpContext.Current.Response.RedirectLocation == null)
{
string filename = FileName + ".xls";
System.IO.StringWriter tw = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(tw);
DataGrid dgGrid = new DataGrid();
dgGrid.DataSource = dt;
dgGrid.DataBind();
//Get the HTML for the control.
dgGrid.RenderControl(hw);
//Write the HTML back to the browser.
//Response.ContentType = application/vnd.ms-excel;
Response.AppendHeader("Content-Disposition", "attachment; filename=" + filename + "");
Response.ContentType = "application/vnd.ms-excel";
Response.Write(tw.ToString());
Response.Flush();
Response.End();
}
}
}
I am unable to download getReports.Tables[1] data because I am getting this error:
server cannot append header after http headers have been sent. mvc
And it is downloading firstfile after error in the browser.
After the download of the first file, the execution hits this line-
Response.End();
That means, the response is ended, and headers have been sent to the client. There's no way you can initiate the download of the second file. If you want to download multiple files in a single button click, you need to zip it into one, and then initiate the download.
To zip the files you can do this-
using System;
using System.IO;
using System.IO.Compression;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
string startPath = #"c:\example\start";
string zipPath = #"c:\example\result.zip";
string extractPath = #"c:\example\extract";
ZipFile.CreateFromDirectory(startPath, zipPath);
ZipFile.ExtractToDirectory(zipPath, extractPath);
}
}
}
Snippet from here.
If you want to make both excel spreadsheets a part of single excel document by putting each one of them as a worksheet, you can use ClosedXML.
I've used ClosedXML (an OpenXML implementation) several times, including in an ASP.NET MVC application and it works like a charm.
Exporting data is a breeze:
using (var memoryStream = new MemoryStream())
{
using (XLWorkbook workbook = new XLWorkbook())
{
using (IXLWorksheet worksheet = workbook.AddWorksheet("WorksheetName"))
{
var toExport = GetData();
worksheet.Row(1).Style.Font.Bold = true;
worksheet.Cell(1, 1).Value = "Column 1";
worksheet.Cell(1, 2).Value = "Column 2";
worksheet.Cell(1, 3).Value = "Column 3";
// Export the data and set some properties
worksheet.Cell(2, 1).Value = toExport.AsEnumerable();
worksheet.RangeUsed().SetAutoFilter();
worksheet.Columns().AdjustToContents();
workbook.SaveAs(memoryStream);
memoryStream.Position = 0;
return File(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "filename.xlsx");
}
}
}
When I am trying to download Project Name, I'm getting a different character for special charter in the Excel export.
What should I do so all my special characters are correctly shown?
protected void lnkExportToExcel_Click(object sender, EventArgs e)
{
//INS1-219
DataTable dt1 = DataHelper.ExecuteQuery(Session["strForExcelReport"].ToString());
DataTable dt3 = new DataTable();
dt3.Columns.Add("Project Code");
dt3.Columns.Add("Project Name");
/// many more columns
foreach (DataRow dr in dt1.Rows)
{
drnew["Project Code"] = dr["ProjectCode"].ToString();
drnew["Project Name"] = dr["ProjectName"].ToString();
drnew["Client"] = dr["OrganizationName"].ToString();
// many, many business rules
dt3.Rows.Add(drnew);
}
// DataTable is now complete
string attachment = "attachment; filename=ProjectInHandDetailsList_" + DateTime.Now.ToString("dd MMM yyyy") + ".xls";
Response.ClearContent();
Response.AddHeader("content-disposition", attachment);
Response.ContentType = "application/vnd.ms-excel";
string tab = "";
foreach (DataColumn dc in dt3.Columns)
{
Response.Write(tab + dc.ColumnName);
tab = "\t";
}
Response.Write("\n");
int i;
foreach (DataRow dr in dt3.Rows)
{
tab = "";
for (i = 0; i < dt3.Columns.Count; i++)
{
Response.Write(tab + dr[i].ToString());
tab = "\t";
}
Response.Write("\n");
}
Response.End();
//END INS1-219
}
With above code a projectname comes out in the Excel sheet like this:
Royal Free Flash Case Study 3–Pleuritic Chest Pa
while this is the value from the database:
Royal Free Flash Case Study 3 – Pleuritic Chest Pa
How do I prevent those strange characters from showing up?
You need to use an Encoding, both in the ContentEncoding header and a StreamWriter to write the strings to the OutputStream. Encoding mismatches are the reason for the strange replacement of characters.
Response.ClearContent();
Response.AddHeader("content-disposition", attachment);
Response.ContentType = "application/vnd.ms-excel";
// set the contentencoding of the http content
Response.ContentEncoding = Encoding.UTF8;
// use a streamwriter that knows how to write strings in
// a specified encoding to a stream
using(var sw = new StreamWriter(Response.OutputStream, Response.ContentEncoding))
{
string tab = "";
foreach (DataColumn dc in dt3.Columns)
{
// use the StreamWriter
sw.Write(tab + dc.ColumnName);
tab = "\t";
}
sw.Write("\n");
int i;
foreach (DataRow dr in dt3.Rows)
{
tab = "";
for (i = 0; i < dt3.Columns.Count; i++)
{
sw.Write(tab + dr[i].ToString());
tab = "\t";
}
sw.Write("\n");
}
}
Response.End();
While exporting Datatable to Excel some columns to fall into a new line. I don't know what the problem is. My code is below:
string attachment = "attachment; filename=Test.xls";
Response.ClearContent();
Response.AddHeader("content-disposition", attachment);
Response.ContentType = "application/vnd.ms-excel";
string tab = "";
foreach (DataColumn dc in transposedTable.Columns)
{
Response.Write(tab + dc.ColumnName);
//tab = "\t";
}
Response.Write("\t");
int i;
foreach (DataRow dr in transposedTable.Rows)
{
Response.Write("\n");
tab = "";
for (i = 0; i < transposedTable.Columns.Count; i++)
{
Response.Write(tab + dr[i].ToString());
tab = "\t";
}
Response.Write("\t");
}
Response.End();
I have tried many ways, but didn't get the exact issue. Is the issue with excel in machine or with my code?
It seems possible that your DataRow data contains newline characters, that is one reason why newlines might be appearing in your data.
Swapping:
Response.Write(tab + dr[i].ToString());
For:
string replacement = Regex.Replace(dr[i].ToString(), #"\t|\n|\r", "");
Response.Write(tab + replacement);
May fix the problem if I did diagnose it correctly.
I am exporting a csv file with the following code from a datatable. however names with accents are not exported correctly
http://screencast.com/t/i9N2mB34DL
var dt=JobContext.GetEngagementLetterReport(SPContext.Current.Site, int.Parse(rdlOption.SelectedValue));
var columnNames = new List<string>
{
Constants.SearchFields.Client.ClientCode,
Constants.SearchFields.Client.ClientName,
Constants.SearchFields.Job.JobCode,
Constants.SearchFields.Job.JobName,
Constants.SearchFields.Job.JobPartner,
Constants.SearchFields.Job.JobDirector,
Constants.SearchFields.Job.JobManager,
Constants.SearchFields.Job.BillContact,
Constants.SearchFields.Job.LineOfService,
Constants.SearchFields.Job.BusinessUnit,
Constants.SearchFields.Job.OperatingUnit,
"JobSiteUrl",
"FileNameUrl"
};
ExcelHelper.ExportDatatabletoExcel(dt, columnNames);
public static void ExportDatatabletoExcel(DataTable dt, List<string> columnNames)
{
try
{
const string attachment = "attachment; filename=elreport.csv";
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.AddHeader("content-disposition", attachment);
HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
string tab = "";
foreach (DataColumn dc in dt.Columns)
{
if (!columnNames.Contains(dc.ColumnName)) continue;
HttpContext.Current.Response.Write(tab + dc.ColumnName);
tab = ";";
}
HttpContext.Current.Response.Write("\n");
int i;
foreach (DataRow dr in dt.Rows)
{
tab = "";
for (i = 0; i < dt.Columns.Count; i++)
{
if(!columnNames.Contains(dt.Columns[i].ColumnName)) continue;
HttpContext.Current.Response.Write(tab + dr[i].ToString());
tab = ";";
}
HttpContext.Current.Response.Write("\n");
}
HttpContext.Current.Response.End();
}
catch (Exception ex)
{
string errorMessage = String.Format("ExportToExcelError: {0}", ex.Message);
LoggingService.LogError(LoggingCategory.General, ex, errorMessage);
throw;
}
}
Try adding the following after setting the content type.
// This is the missing part from your original code to set the charset and encoding - if this does not work, replace it with appropriate value, eg
Response.Charset = "utf-8";
Response.ContentEncoding = Encoding.UTF8;
// You might want to use this content type or experiment with appropriate MIME type
Response.ContentType = "text/csv";
TQ.