Exporting GridView to Excel without gridview cells with hyperlinks showing red - c#

I have an ASP.Net 4.0 GridView and a button which exports the GridView data to Excel. This all works fine. However, within the GridView, the text in three cells of each row are red because they are hyperlinks. When I export the data to Excel, these cells are still red. I want them to be black. How do I do this? Here's my code:
Response.ClearContent();
Response.AppendHeader("content-disposition", "attachment; filename=Mobile.xls");
Response.ContentType = "application/excel";
StringWriter stringWriter = new StringWriter();
HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);
foreach (GridViewRow gridViewRow in gvResults.Rows)
{
gridViewRow.ForeColor = Color.Black;
foreach (TableCell gridViewRowTableCell in gridViewRow.Cells)
gridViewRowTableCell.Style["forecolor"] = "#000000";
if (gridViewRow.RowType == DataControlRowType.DataRow)
{
for (int columnIndex = 0; columnIndex < gridViewRow.Cells.Count; columnIndex++)
{
gridViewRow.Cells[columnIndex].Attributes.Add("class", "text");
}
}
}
gvResults.RenderControl(htmlTextWriter);
string style = #"<style> .text { mso-number-format:\#; } </style> ";
Response.Write(style);
Response.Write(stringWriter.ToString());
Response.End();
And here's the code for the links. This runs OnDataBound:
foreach (GridViewRow row in gvResults.Rows)
{
if (row.RowType == DataControlRowType.DataRow || row.RowType == DataControlRowType.EmptyDataRow)
{
string imei = row.Cells[0].Text;
if (imei != " ")
{
string imeiLink = "window.location='SmartphoneInventory.aspx?imei=" + imei + "';";
row.Cells[0].Attributes.Add("onClick", String.Format(imeiLink));
row.Cells[0].Text = "<span style='color:red'>" + row.Cells[0].Text + "</span>";
}
string phonenumber = row.Cells[1].Text;
if (phonenumber != " ")
{
string phonenumberLink = "window.location='SmartphoneInventory.aspx?phonenumber=" + phonenumber + "';";
row.Cells[1].Attributes.Add("onClick", String.Format(phonenumberLink));
row.Cells[1].Text = "<span style='color:red'>" + row.Cells[1].Text + "</span>";
}
int cellCount = row.Cells.Count;
string empName = row.Cells[cellCount - 1].Text;
if (empName != " ")
{
string empNameLink = "window.location='DevicesByEmployee.aspx?empName=" + empName + "';";
row.Cells[cellCount - 1].Attributes.Add("onClick", String.Format(empNameLink));
row.Cells[cellCount - 1].Text = "<span style='color:red'>" + row.Cells[cellCount - 1].Text + "</span>";
}
}
}
I guess what I need is how to re-style the span. Is this possible? The GridView autogenerates its columns.

Get the LinkButton Text, assign it to the GridView Cell Text and Remove control.
Here is ho I do it in the header:
C#
foreach (TableCell c in gv.HeaderRow.Cells) {
if (c.HasControls) {
c.Text = (c.Controls(0) as LinkButton).Text;
c.Controls.Clear();
}
}
VB.NET
For Each c As TableCell In gv.HeaderRow.Cells
If c.HasControls Then
c.Text = TryCast(c.Controls(0), LinkButton).Text
c.Controls.Clear()
End If
Next
EDIT:
Create an extension method:
C#
[Extension()]
public string StripTags(string html)
{
return Regex.Replace(html, "<.*?>", "");
}
VB.NET
<Extension> _
Public Function StripTags(html As String) As String
Return Regex.Replace(html, "<.*?>", "")
End Function
It will remove tags from your string, therefore your style. Use as follows:
foreach (GridViewRow gridViewRow in gvResults.Rows)
{
gridViewRow.ForeColor = Color.Black;
foreach (TableCell gridViewRowTableCell in gridViewRow.Cells)
gridViewRowTableCell.Style["forecolor"] = "#000000";
if (gridViewRow.RowType == DataControlRowType.DataRow)
{
for (int columnIndex = 0; columnIndex < gridViewRow.Cells.Count; columnIndex++)
{
gridViewRow.Cells[columnIndex].Text = gridViewRow.Cells[columnIndex].Text.StripTags();
}
}
}

Related

Generating excel clears viewbag/tempdata

I am trying to generate excel with following code
public void GenerateExcel(string reportName, DataTable dt)
{
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.Buffer = true;
Response.ContentType = "application/ms-excel";
Response.Write(#"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">");
Response.AddHeader("Content-Disposition", "attachment;filename= " + reportName + ".xls");
Response.Charset = "utf-8";
Response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1250");
StringWriter ws = new StringWriter();
ws.Write("<font style='font-size:10.0pt; font-family:Calibri;'>");
// ws.Write("<BR><BR><BR>");
//sets the table border, cell spacing, border color, font of the text, background, foreground, font height
ws.Write("<Table border='1' bgColor='#ffffff' " +
"borderColor='#000000' cellSpacing='0' cellPadding='0' " +
"style='font-size:10.0pt; font-family:Calibri; background:white;'>");
string strBoldCell = "<TD bgColor='#c9c7c3' style=\"font-weight: bold\">{0}</TD>";
string strRedCell = "<TD style=\"background-color:#ff4d4d\">{0}</TD>";
string strCell = "<TD>{0}</TD>";
string strColSpan = "<TD colspan={0} style=\"font-weight: bold\">{1}</TD>";
int r;
int c;
if (dt.Rows.Count > 0)
{
try
{
ws.Write("<TR>");
for (c = 0; c < dt.Columns.Count; c++)
{
ws.Write(string.Format(strBoldCell, dt.Columns[c].ColumnName).Replace("_", "‌"));
}
ws.Write("</TR>");
ws.Write("\n");
for (r = 0; r < dt.Rows.Count; r++)
{
ws.Write("<TR>");
for (c = 0; c < dt.Columns.Count; c++)
{
if (string.IsNullOrEmpty(dt.Rows[r][dt.Columns[c].ColumnName].ToString()) == false)
{
if (dt.Rows[r]["Comment"].ToString() != null && dt.Rows[r]["Comment"].ToString() != "")
{
ws.Write(string.Format(strRedCell, dt.Rows[r][dt.Columns[c].ColumnName].ToString().Replace('_', ' ')));
}
else
{
ws.Write(string.Format(strCell, dt.Rows[r][dt.Columns[c].ColumnName].ToString().Replace('_', ' ')));
}
}
else
{
if (dt.Rows[r]["Comment"].ToString() != null && dt.Rows[r]["Comment"].ToString() != "")
{
ws.Write(string.Format(strRedCell, " "));
}
else
{
ws.Write(string.Format(strCell, " "));
}
}
}
ws.Write("</TR>");
ws.Write("\n");
}
}
catch (Exception ex)
{
throw ex;
}
}
else
{
ws.Write("<Tr>");
ws.Write(string.Format(strColSpan, 10, "No records found"));
ws.Write("</Tr>");
}
ws.Write("</Table>");
ws.Write("</Font>");
Response.Write(ws.ToString());
Response.Flush();
Response.End();
}
by calling above method in main method as follows
if (Cnt != 0)
{
TempData["Error"] = "There were issues with the Excel Import: Total Records: " + result.Rows.Count+" Error Row Count: "+Cnt;
}
else
{
TempData["Error"] = "No error found in given excel: Total Records: " + result.Rows.Count;
}
GenerateExcel("OutputFile" + DateTime.Now.ToString("MMddyyyyhhmmss"), result);
return View();
also trying to pass Tempdata to view but the problem is excel is generating successfully but tempdata does not showing anything in view.
if i comment the code of calling GenerateExcel method tempdata is perfectly showing on view..why this is happening?
Please Try moving calling function before setting tempdata like:
GenerateExcel("OutputFile" + DateTime.Now.ToString("MMddyyyyhhmmss"), result);
if (Cnt != 0)
{
TempData["Error"] = "There were issues with the Excel Import: Total Records: " + result.Rows.Count+" Error Row Count: "+Cnt;
}
else
{
TempData["Error"] = "No error found in given excel: Total Records: " + result.Rows.Count;
}
return View();

c# equivalent to document.getElementById("ListBox"+i+"Item"+j).selected=true

I've created a dynamic webpage using strictly html, javascript, and MS Access. While it was functional, locally, there were complications deploying it. Since I have ported the data to MySQL and am trying to use Visual Studio's aspx.cs to do much of what the javascript did previously.
I have a screen that populates a dynamic set of rows based on a query result (two rows per record for aesthetics), one of the cells contains a drop down menu(html select/ asp:ListBox).
When I had everything only on javascript, I could create the cell, then create its contents, then set the selected value using:
document.getElementById("StatusDD" + rowCount).value = reader.GetValue(i);
From what I've gathered so far, the rough equivalent is:
ListItem li = StatusDD1.Items.FindByValue(reader.GetValue(i));
li.Selected = true;
However, I cannot simply hardcode StatusDD1 thru StatusDDx (for one, at the beginning my hardcoded set might be larger than the number of records returned, and two eventually the rows returned will be larger than the set of hardcoded values).
So what I did was I created the following function:
protected void setSelected(string selectId, string value)
{
/*Need to put something here to make the following work*/
selectId.Items.FindByValue(value).Selected = true;
}
The selectId being passed in is the name/id of the ListBox and the value is the value coming back from the query.
It's called like:
setSelected("StatusDD" + rowCount, (string)reader.GetValue(i));
If I could, for lack of better phrase, materialize the name created by "StatusDD"+rowCount, I could pass that name in as if I was passing in a ListBox, rather than a string.
Alternatively, if there was a way to select the ListBox from an array where I could do a conditional check WHERE/IF ListBox.Name = selectId, something like the following PseudoCode:
ListBox a = ListBox.NameMatches(selectId);
a.Items.FindByValue(value).Selected = true;
Currently ListBoxes are being created by defining the box in a string and then passing that string into an HtmlTableCell:
HtmlTable myTable = new HtmlTable();
HtmlTableRow newRow;
string cellId;
string cellContents;
int rowCount = 1;
string statusDisabled = "";
while (reader.Read()){
newRow = new HtmlTableRow();
myTable.Rows.Add( newRow );
...
...
cellContents = "<asp:ListBox name='StatusDD" + rowCount + "' id='StatusDD" + rowCount + "' style='width:100%; " + statusDisabled + "' value='" + reader.GetValue(i) + "' onchange='markNeedSave(" + (rowCount + 1) + ")'><asp:ListItem value='0'></asp:ListItem><asp:ListItem value='1'>New</asp:ListItem>....asp:ListBox>";
newRow.Cells.Add(new HtmlTableCell{InnerHtml = cellContents});
}
If it helps, here's how I had it working in javascript:
while (!rs.EOF) {
rowa = table.insertRow(rowCount);
rowa.id = "RECORD" + rowCount + "a";
cell = rowa.insertCell(i + 1);
cell.id = "RECORD" + rowCount + "_CELL" + (i + 1);
for (i = 0; i < 8; i++) {
cell.innerHTML = "<select name='StatusDD" + rowCount + "' id='StatusDD" + rowCount + "' style='width:100%' value='" + rs.fields(i).value + "' onchange='markNeedSave(" + (rowCount + 1) + ")'><option value='NONE'></option><option value='New'>New</option>...</select>";
if (readonly) {
document.getElementById("StatusDD" + rowCount).disabled = true;
}
document.getElementById("StatusDD" + rowCount).value = rs.fields(i).value;
}
...
}
OK, got the ListBox to work, but as I was researching, and when I finally got it to work, I discovered that what I wanted was the DropDownList, not the ListBox, but the same fixes needed to be done in order to get either to work.
I use the following function now:
protected void setSelected(string selectId, string value)
{
PlaceHolder TCS = Page.FindControl("TestingCS") as PlaceHolder;
DropDownList ddl = TCS.FindControl(selectId) as DropDownList;
if (ddl != null)
{
ddl.SelectedValue = value;
ListItem item = ddl.Items.FindByValue(value);
if(item != null)
{ item.Selected = true;}
}
}
Also, for my cell contents that just contain data using the following is fine:
cellContents = "<someString>";
newRow.Cells.Add(new HtmlTableCell{InnerHtml = cellContents});
but for my drop down (or list box) I need to use:
cell = new HtmlTableCell();
newRow.Cells.Add(cell);
DropList = new DropDownList();
DropList.ID = "StatusDD" + rowCount;
DropList.Items.Add(new ListItem("", "0"));
DropList.Items.Add(new ListItem("New", "1"));
...
cell.Controls.Add(DropList);
setSelected(DropList.ID, (string)(reader.GetValue(i)));
A smoother solution:
protected void setSelected(DropDownList ddl, string value)
{
ListItem item = ddl.Items.FindByValue(value);
if (item != null)
{ item.Selected = true; }
}
...
protected void accessRecord()
{
...
DropList = new DropDownList();
DropList.ID = "StatusDD" + rowCount;
DropList.Attributes["onChange"] = "javascript:markNeedSave(" + rowCount + ");";
DropList.Items.Add(new ListItem("", "0"));
DropList.Items.Add(new ListItem("New", "1"));
...
cell.Controls.Add(DropList);
setSelected(DropList,(string)reader.GetValue(i));
}
...
It sounds like the function you're looking for is FindControl. This can be used from the Page, or any parent control you might have created to hold your output.
An example implementation of your setSelected method might look like this:
protected void SetSelected(string selectId, string value)
{
var lb = Page.FindControl(selectId) as ListBox;
if (lb != null)
{
var item = lb.Items.FindByValue(value)
if(item != null)
item.Selected = true;
}
}

unable to read PDF controls in c#

Am tryinng to read PDf and inside PDF controls. my pdf is generated by adobe pdf library. getting null acro fields.but my form have 4 check boxes. 4 check boxed i can use to check or uncheck . i want checkbox is checked or not.
i used itextsharp to read pdf but, it is not finding controls.
private static string GetFormFieldNamesWithValues(PdfReader pdfReader)
{
return string.Join("\r\n", pdfReader.AcroFields.Fields
.Select(x => x.Key + "=" +
pdfReader.AcroFields.GetField(x.Key) + "=" + pdfReader.AcroFields.GetFieldType(x.Key)).ToArray());
}
static void Main(string[] args)
{
DataTable filedDetails;
DataRow dr;
string cName="";
string cType = "";
string cValue = "";
int txtCount = 0;
int btnCount = 0;
int chkBoxCount = 0;
int rdButtonCount = 0;
int dropDownCount = 0;
var fileName = "C:\\PreScreenings\\ViewPDF Cien.pdf";// PDFFileName.Get(context);
//var fileName = #"C:\Users\465sanv\Downloads\Read-PDF-Controls-master\ReadPDFControl\Input\David1990.pdf";
var fields = GetFormFieldNamesWithValues(new PdfReader(fileName));
string[] splitRows = fields.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
filedDetails = new DataTable("PDF Table");
filedDetails.Columns.AddRange(new[] { new DataColumn("Control Name"), new DataColumn("Control Type"), new DataColumn("Control Value") });
foreach (string row in splitRows)
{
dr = filedDetails.NewRow();
string[] str = row.Split("=".ToCharArray(), StringSplitOptions.None);
cName = str[0].ToString();
cValue = str[1].ToString();
if (str[2].ToString() == "1")
{
btnCount++;
cType = "Button" + btnCount.ToString();
}
else if (str[2].ToString() == "2")
{
chkBoxCount++;
cType = "Check Box" + chkBoxCount.ToString();
}
else if (str[2].ToString() == "3")
{
rdButtonCount++;
cType = "Radio Button" + rdButtonCount.ToString();
}
else if (str[2].ToString() == "4")
{
txtCount++;
cType = "Text Field" + txtCount.ToString();
}
else if (str[2].ToString() == "6")
{
dropDownCount++;
cType = "Drop Down" + dropDownCount.ToString();
}
dr[0] = cName;
dr[1] = cType;
dr[2] = cValue;
filedDetails.Rows.Add(dr);
}
}

inserting data into database for different object type at the same time?

Here is my code. I am trying to insert data by using this MyResponses(). This is my next click event.
nextclick event
{
Section surveySection = DataAccess.AccessSurveySectionByParameters(currentSurvey.EmplID, currentSurvey.UnitId, currentSurvey.SurveyId, currentSurvey.Sort.ToString(), NextStep, GetSurveyResponses());
PopulateSurveySection(currentSurvey, surveySection);
}
private string MyResponses()
{
string resp = "";
foreach (Control ctr in pnlSurveySection.Controls)
{
if (ctr is Table)
{
Table tbl = ctr as Table;
foreach (TableRow tr in tbl.Rows)
{
string sres = "";
string currid = tr.Cells[0].Attributes["ID"];
TableCell tc = tr.Cells[1];
if(currid.StartsWith("editable"))
{
currid.Substring(0, 14);
foreach (Control ctrc in tc.Controls)
{
if (ctrc is TextBox)
{
sres = currid + "||" + (ctrc as TextBox).Text.Trim();
}
else if (ctrc is RadioButtonList)
{
sres = currid + "||" + (ctrc as RadioButtonList).SelectedValue;
}
else if (ctrc is DropDownList)
{
sres = currid + "||" + (ctrc as DropDownList).SelectedValue;
}
else if (ctrc is CheckBoxList)
{
sres = currid + "||" + (ctrc as CheckBoxList).SelectedItem.ToString() + "|";
}
}
}
resp = resp + (string.IsNullOrEmpty(resp) ? "|||" : "") + sres;
}
}
It is not inserting data. and not giving me any error..Any suggestion appreciate
Thanks

Unable to Export the Dynamically added row to Gridview to Excel

I have tried Exporting GridView to Excel but observed that
the Dynamically added last Row to Gridview is not exported to excel.
I have two datasets first one binds the data directly to Gridview.
After Which I add the last row from another DataSet.
In the page I'm able to see the result as Expected but when exported excel I'm not.
Below is my code:
DataSet dsgrid = SqlHelper.ExecuteDataset(DBConnectionString.ConnectionString, CommandType.StoredProcedure, "usp_Training_GetCirclescoreCardReport ", sqlparam);
if (TrainingUtil.isDataSetValid(dsgrid))
{
RSGScoreCard_Grid.DataSource = dsgrid;
RSGScoreCard_Grid.DataBind();
AddOverallRow(dsgrid);
}
else RSGScoreCard_Grid.DataBind();
Adding Overall row at bottom:
#region Add OverallRow
private void AddOverallRow(DataSet dsgrid)
{
using (GridViewRow gr = new GridViewRow(RSGScoreCard_Grid.Rows.Count + 1, 0, DataControlRowType.DataRow, DataControlRowState.Normal))
{
for (int i = 0; i < 6; i++)//6 is the column count for overall row
{
using (TableCell tc = new TableCell())
{
gr.Cells.Add(tc);
if (i == 0)
{
gr.Cells[i].ColumnSpan = 4;
gr.Cells[i].Text = "Overall";
gr.Cells[i].Attributes.Add("class", "fcol");
gr.Cells[i].Attributes.Add("style", "font-weight:bold;padding-left:20%");
}
else gr.Cells[i].Attributes.Add("style", "font-weight:bold");
}
}
if (dsgrid.Tables[1] != null)//creating a dynamic row to gridview
if (dsgrid.Tables[1].Rows.Count > 0)
{
gr.Cells[1].Text = dsgrid.Tables[1].Rows[0][5].ToString();
gr.Cells[1].Width = Unit.Percentage(8);
gr.Cells[2].Text = dsgrid.Tables[1].Rows[0][6].ToString();
gr.Cells[2].Width = Unit.Percentage(8);
gr.Cells[3].Text = dsgrid.Tables[1].Rows[0][7].ToString();
gr.Cells[3].Width = Unit.Percentage(8);
gr.Cells[4].Text = dsgrid.Tables[1].Rows[0][8].ToString();
gr.Cells[4].Width = Unit.Percentage(8);
gr.Cells[5].Text = dsgrid.Tables[1].Rows[0][9].ToString();
gr.Cells[5].Width = Unit.Percentage(8);
}
gr.Attributes.Add("class", "row2");
RSGScoreCard_Grid.Controls[0].Controls.AddAt(RSGScoreCard_Grid.Rows.Count + 1, gr);
}
}
#endregion
and Last my code to Export the GrieView:
protected void btnExport_Click(object sender, EventArgs e)
{
TrainingUtil.Export(ddlOptions.SelectedItem.Text.ToString().Replace(" ", string.Empty) + "_" + ddlVerticals.SelectedItem.Text.ToString().Replace(" ", string.Empty) + "_" + ddlLernerGroups.SelectedItem.Text.ToString().Replace(" ", string.Empty), RSGScoreCard_Grid, "For the Month/Year: " + ddlFromMonths.SelectedItem.Text.ToString()+"/"+ddlYears.SelectedItem.Text.ToString(), RSGScoreCard_Grid.HeaderRow.Cells.Count);
}
public override void VerifyRenderingInServerForm(Control control)
{
/* Confirms that an HtmlForm control is rendered for the specified ASP.NET
server control at run time. */
}
the Export Method in TrainingUtil class
#region Export
public static void Export(string filename, GridView grid, string Heading, int ColumnsCount)
{
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", filename + ".xls"));
HttpContext.Current.Response.ContentType = "application/ms-excel";
using (StringWriter sw = new StringWriter())
{
using (HtmlTextWriter htw = new HtmlTextWriter(sw))
{
grid.HeaderStyle.BackColor = System.Drawing.Color.Cyan;
//Cells color settings
GridViewRow row = new GridViewRow(0, 0, DataControlRowType.DataRow, DataControlRowState.Normal);
TableCell cell = new TableCell();
cell.Text = String.Format("{0}", Heading);
cell.ColumnSpan = ColumnsCount;
cell.Attributes.Add("align", "center");
cell.Attributes.Add("class", "yellow");
row.Cells.Add(cell);
grid.Controls[0].Controls.AddAt(0, row);
foreach (GridViewRow gridRow in grid.Rows)
{
foreach (TableCell tcGridCells in gridRow.Cells)
{
tcGridCells.Attributes.Add("class", "sborder");
}
}
grid.RenderControl(htw);
//Add the style sheet class here
HttpContext.Current.Response.Write(#"<style> .sborder { color : Black;border : 1px Solid Black; } .yellow {background-color:yellow;color:black;} </style> ");
HttpContext.Current.Response.Write(sw.ToString());
HttpContext.Current.Response.End();
}
}
}
#endregion
Can any help me out.Why I'm not able to export the last row.
Thanks in advance
I think in every post back your not binding the dynamically added rows.
Try to find the control which cause the postback and bind the data once again.
Code to find the postback control ex:-
public static Control GetPostBackControl(Page page)
{
Control control = null;
string ctrlname = page.Request.Params.Get("__EVENTTARGET");
if (ctrlname != null && ctrlname != string.Empty)
{
control = page.FindControl(ctrlname);
}
else
{
foreach (string ctl in page.Request.Form)
{
Control c = page.FindControl(ctl);
if (c is System.Web.UI.WebControls.Button)
{
control = c;
break;
}
}
}
return control;
}

Categories