Save repeater data to CSV

by Andrei Hetel 9. September 2008 10:36

I was working recently on a web project. One of the requirements was to save the data from a repeater control (I decide to use repeater and not DataGrid because of speed) into a CSV file. Don't know if this is the best method or not, but this is the way I did it. Relevant code in ASPX page:

<table>
<asp:Repeater ID="test" runat="server" >
  <HeaderTemplate>
    <tr>
      <td>Item</td>
      <td>Count</td>
      <td>Price</td>
      <td>VAT</td>
      <td>Total</td>
    </tr>
  </HeaderTemplate>
  <ItemTemplate>
    <tr>
      <td><asp:label ID="Item" Text=<%#DataBinder.Eval(Container, "DataItem.Item")%> runat="server" /></td>
      <td><asp:label ID="Cnt" Text=<%#DataBinder.Eval(Container, "DataItem.Cnt")%> runat="server" /></td>
      <td><asp:label ID="Price" Text=<%#DataBinder.Eval(Container, "DataItem.Price")%> runat="server" /></td>
      <td><asp:label ID="VAT" Text=<%#DataBinder.Eval(Container, "DataItem.VAT")%> runat="server" /></td>
      <td><asp:label ID="Total" Text=<%#DataBinder.Eval(Container, "DataItem.Total")%> runat="server" /></td>
    </tr>
  </ItemTemplate>
</asp:Repeater>
</table>
<asp:Button id="Export" Text="Export" runat="server" />

 

We need the following class:

 

Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.IO
Imports System.Text

Public Class CCSVExport
  Private _pPage As Page = Nothing
  Private _Title As String
  Private _ColumnList As ArrayList
  Private _FName As String

  Public Sub New(ByVal pPage As Page, ByVal tit As String, ByVal fName As String, ByVal colList As ArrayList)
    _pPage = pPage
    _Title = tit
    _FName = fName
    _ColumnList = colList
  End Sub

  Public Sub ExportRepeater(ByVal rpt As Repeater)
    Dim context As System.Web.HttpContext
    Dim byteArray() As Byte

    context = System.Web.HttpContext.Current
    context.Response.Clear()
    context.Response.Buffer = True
    context.Response.ContentType = "application/vnd.ms-excel"
    context.Response.Charset = ""
    _pPage.EnableViewState = False
    context.Response.AddHeader("Content-Disposition", "attachment;filename=" & _FName & ";")
    byteArray = System.Text.Encoding.ASCII.GetBytes(BuildData(rpt).ToString)
    context.Response.BinaryWrite(byteArray)
    context.Response.End()
  End Sub

  Private Function BuildData(ByVal rpt As Repeater) As StringBuilder

    Dim ri As RepeaterItem
    Dim currentLine As String
    Dim arrayIndex As Int16
    Dim sb As New StringBuilder

    sb.AppendLine(_Title)
    For Each ri In rpt.Items

      currentLine = ""
      If ri.ItemType = ListItemType.AlternatingItem Or ri.ItemType = ListItemType.Item Then
        For arrayIndex = 0 To _ColumnList.Count - 1
          currentLine &= CType(ri.FindControl(_ColumnList.Item(arrayIndex)), Label).Text.Trim & ","
        Next arrayIndex
        sb.AppendLine(currentLine)
      End If
    Next ri
    Return sb
  End Function
End Class

 

Code in page load, just binding the repeater to a datatable:

 

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

  test.DataSource = dt
  test.DataBind()

End Sub

 

Finally, export the data:

Protected Sub Export_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Export.Click

  Dim fileTitle As String
  Dim export As CCSVExport
  Dim arrFields As ArrayList

  fileTitle = "Test"
  arrFields = New ArrayList

  arrFields.Add("Item")
  arrFields.Add("Cnt")
  arrFields.Add("Price")
  arrFields.Add("VAT")
  arrFields.Add("Total")
  export = New CCSVExport(Page, fileTitle, "test.csv", arrFields)
  export.ExportRepeater(test)
End Sub

 

Index a repeater – pretty simple

by Andrei Hetel 6. February 2008 12:45

Piece of code presented here simply add a column, not related with content of the repeater, which index current line of data.
Repeater definition:

 

<asp:Repeater id="RB" runat="server">
  <HeaderTemplate>
    <tr>
      <td align="right">#</td>
      <td>User</td>
      <td align="right">Points</td>
    </tr>
  </HeaderTemplate>
  <ItemTemplate>
    <tr>
      <td align="right"><asp:Label ID="t5" runat="server"></asp:Label></td>
      <td><%#DataBinder.Eval(Container.DataItem, "UserName")%></td>
      <td align="right"><%#DataBinder.Eval(Container.DataItem, "TotalPoints")%></td>
    </tr>
  </ItemTemplate>
</asp:Repeater>

 

In code behind, first declare a variable:

 

Private CounterOverallTop As Integer = 1

 

Don’t forget to bind your data to the repeater, something like:

RB.DataSource = … your data source RB.DataBind()

 

Following code will populate index column.

 

Protected Sub RB_ItemDataBound(ByVal sender As Object, _
                                                   ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) _
                                                   Handles RB.ItemDataBound

  If (e.Item.ItemType = ListItemType.Item) Or _
    (e.Item.ItemType = ListItemType.AlternatingItem) Then

      DirectCast(e.Item.FindControl("t5"), Label).Text = CounterOverallTop
      CounterOverallTop += 1

  End If

End Sub