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.
Related
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();
Can anybody help me understand what these lines of codes really means...i understand it but not exactly...i mean what foreach is exactly doing here???
if (dt.Rows.Count > 0)
{
//GridView1.Visible = true;
Gridview1.DataSource = dt;
Gridview1.DataBind();
StringBuilder sb = new StringBuilder();
foreach (DataColumn col in dt.Columns)
{
sb.Append(col.ColumnName + ",");
}
sb.Remove(sb.Length - 1, 1);
sb.Append(Environment.NewLine);
foreach (DataRow row in dt.Rows)
{
for (int i = 0; i < dt.Columns.Count; i++)
{
sb.Append(row[i].ToString() + ",");
}
sb.Append(Environment.NewLine);
}
Response.ClearHeaders();
Response.AppendHeader("Content-Disposition", "attachment; filename=CDR OF " + TextBox1.Text + ".csv");
Response.AppendHeader("Content-Length", sb.Length.ToString());
Response.ContentType = "text/csv";
Response.Write(sb.ToString());
Response.Flush();
Response.End();
}
else
{
//GridView1.Visible = false;
Show("No CDR Found!");
}
And can we use StringWriter or string in place of StringBuilder ???
The first loop lists all your column names with a comma:
colname1,colname2,colname3,
The Remove then removes the last comma and adds a newline
colname1,colname2,colname3\n
The second loop lists all your values of each column of each row
colname1,colname2,colname3\n
row1col1value,row1col2value,row1col3value,\n -- note that the comma is NOT removed here
row2col1value,row2col2value,row2col3value,\n
row3col1value,row3col2value,row3col3value,\n
row4col1val etc...
And yes, I think you can use a string instead of the string builder.
The first foreach is appending the column header names.
The second is appending the cell values. Both in comma separated way.
Ao you are converting a GridView to a csv.
Why don't use a simple converter like the CSV helper.
Has everything you need.
CSV Helper
Looks like the code is trying to generate csv file with headers for the data table. The first for each loops through the columns in DataTable and generates a comma separated column name string (referred by StringBuffer).
sb.Remove(sb.Length - 1, 1);
sb.Append(Environment.NewLine);
The above code snippet removes the last comma from the comma separated column name string and then adds a new line
foreach (DataRow row in dt.Rows)
{
for (int i = 0; i < dt.Columns.Count; i++)
{
sb.Append(row[i].ToString() + ",");
}
sb.Append(Environment.NewLine);
}
the loop above iterates through each row of DataTable, and creates a comma separated string for each column value of the. After each row is processed, a new line is added so that the next row contents are added as comma separated string in new line.
The first loop is taking each column name from Datatable and appending with a separator comma to a stringBuilder. Then it is trimming the last comma appended and adding a new line to it.
The second loop is taking all the data values of DataRow(row by row) , then comma and appending to the same stringbuilder.
I'm exporting some data from a GridView to a .txt file.
This is the code:
private void ExportGridToExcel()
{
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
string FileName = "Export" + DateTime.Now + ".txt";
StringBuilder strbldr = new StringBuilder();
Response.ContentType = "application/text";
Response.AddHeader("Content-Disposition", "attachment;filename=" + FileName);
Response.ContentEncoding = System.Text.Encoding.Unicode;
Response.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble());
Response.Cache.SetCacheability(HttpCacheability.NoCache);
for (int i = 0; i < GridView1.Columns.Count; i++)
{
//separting header columns text with comma operator
strbldr.Append(GridView1.Columns[i].HeaderText + ',');
}
//appending new line for gridview header row
strbldr.Append("\n");
for (int j = 0; j < GridView1.Rows.Count; j++)
{
for (int k = 0; k < GridView1.Columns.Count; k++)
{
//separating gridview columns with comma
strbldr.Append(GridView1.Rows[j].Cells[k].Text + ',');
strbldr.Replace("<", "<");
strbldr.Replace(">", ">");
}
//appending new line for gridview rows
strbldr.Append("\n");
}
GridView1.AllowPaging = false;
Response.Output.Write(strbldr.ToString());
Response.End();
}
protected void Button3_Click(object sender, EventArgs e)
{
ExportGridToExcel();
}
This works, however I need to remove all html tags in the export as the above code seems to add <p> tags to the different columns? Anybody know how I can do this?
You could use utility function based on regex to remove html tags:
public string RemoveHtmlTags(string source)
{
return Regex.Replace(source, "<.*?>", "");
}
This will replace all tags like "<b>" or "<span/>" with empty string.
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.
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