question

DavidChase-4918 avatar image
0 Votes"
DavidChase-4918 asked YijingSun-MSFT commented

Export GridView image to Excel

We have an asp.net web application that we want to export a GridView that includes an image column to Excel. Our code works fine but now we added an image control and we want the actual picture to export. Below is our GridView and code that is working but I am not sure how to code for the ImageButton control (we are open to using just an Image control if that would work better but I think the concept is the same. If I export the URL for the image it works fine but does not export the actual image.

     <asp:GridView ID="GridView1" runat="server" DataSourceID="SqlPartInventory" AutoGenerateColumns="False" DataKeyNames="InventoryID" Visible="True">
         <Columns>
             <asp:BoundField DataField="InventoryID" HeaderText="InventoryID" InsertVisible="False" ReadOnly="True" SortExpression="InventoryID" />
             <asp:BoundField DataField="PartNumber" HeaderText="PartNumber" SortExpression="PartNumber" />
             <asp:BoundField DataField="PartDescription" HeaderText="PartDescription" SortExpression="PartDescription" />
             <asp:BoundField DataField="VehicleYear" HeaderText="VehicleYear" SortExpression="VehicleYear" />
             <asp:BoundField DataField="VehicleMake" HeaderText="VehicleMake" SortExpression="VehicleMake" />
             <asp:BoundField DataField="VehicleModel" HeaderText="VehicleModel" SortExpression="VehicleModel" />
             <asp:BoundField DataField="Qty" HeaderText="Qty" SortExpression="Qty" />
             <asp:BoundField DataField="SellingPrice" HeaderText="SellingPrice" SortExpression="SellingPrice" />
             <asp:BoundField DataField="PartCost" HeaderText="PartCost" SortExpression="PartCost" />
             <asp:BoundField DataField="PartQuality" HeaderText="PartQuality" SortExpression="PartQuality" />
             <asp:BoundField DataField="QualityText" HeaderText="QualityText" ReadOnly="True" SortExpression="QualityText" />
             <asp:BoundField DataField="Location" HeaderText="Location" SortExpression="Location" />
             <asp:BoundField DataField="RepairOrderID" HeaderText="RepairOrderID" SortExpression="RepairOrderID" />
             <asp:CheckBoxField DataField="Available" HeaderText="Available" SortExpression="Available" />
             <asp:BoundField DataField="PartNotes" HeaderText="PartNotes" SortExpression="PartNotes" />
             <asp:TemplateField>
                 <ItemTemplate>
                     <asp:ImageButton ID="IBtnPhoto" runat="server" />
                 </ItemTemplate>
             </asp:TemplateField>
         </Columns>
     </asp:GridView>
    
     Private Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
         If e.Row.RowType = DataControlRowType.DataRow Then
             Dim img As ImageButton = e.Row.FindControl("IBtnPhoto")
             Dim strurl As String = ConfigurationManager.AppSettings("appurl")
             Dim strurlPhy As String = Server.MapPath("~/Photos/_Parts/") & DataBinder.Eval(e.Row.DataItem, "InventoryID") & ".jpg"
    
             If File.Exists(strurlPhy) = False Then
                 img.CssClass = "hide"
             Else
                 img.ImageUrl = "../Photos/_Parts/" & DataBinder.Eval(e.Row.DataItem, "InventoryID") & ".jpg"
             End If
             img.AlternateText = DataBinder.Eval(e.Row.DataItem, "InventoryID")
    
         End If
     End Sub
    
     Private Sub LBtnExport_Click(sender As Object, e As EventArgs) Handles LBtnExport.Click
         GridView1.Visible = True
         GridView1.DataBind()
         UtilClass.Export("MABParts.xls", GridView1, "Internal Parts Inventory")
     End Sub
    
    
     Public Shared Sub Export(ByVal fileName As String, ByVal gv As GridView, ByVal strTitle As String)
         If gv.AllowPaging = True Then
             gv.AllowPaging = False
         End If
    
         HttpContext.Current.Response.Clear()
         HttpContext.Current.Response.AddHeader("content-disposition", String.Format("attachment; filename={0}", fileName))
         'HttpContext.Current.Response.ContentType = "application/ms-excel"
         HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    
         Dim sw As StringWriter = New StringWriter
         Dim htw As HtmlTextWriter = New HtmlTextWriter(sw)
         '  Create a form to contain the grid
         Dim table As Table = New Table
         table.GridLines = gv.GridLines
         If strTitle <> "" Then
             strTitle = "<p><b>" & strTitle & "</b></p>"
             sw.Write(strTitle)
         End If
    
         '  add the header row to the table
         If (Not (gv.HeaderRow) Is Nothing) Then
             UtilClass.PrepareControlForExport(gv.HeaderRow)
             table.Rows.Add(gv.HeaderRow)
         End If
         '  add each of the data rows to the table
         For Each row As GridViewRow In gv.Rows
             UtilClass.PrepareControlForExport(row)
             table.Rows.Add(row)
         Next
         '  add the footer row to the table
         If (Not (gv.FooterRow) Is Nothing) Then
             UtilClass.PrepareControlForExport(gv.FooterRow)
             table.Rows.Add(gv.FooterRow)
         End If
         '  render the table into the htmlwriter
         table.RenderControl(htw)
    
         '  render the htmlwriter into the response
         HttpContext.Current.Response.Write(sw.ToString)
    
         HttpContext.Current.Response.End()
     End Sub
    
     Private Shared Sub PrepareControlForExport(ByVal control As Control)
         Dim i As Integer = 0
         Do While (i < control.Controls.Count)
             Dim current As Control = control.Controls(i)
             If current.Visible Then
                 If (TypeOf current Is LinkButton) Then
                     control.Controls.Remove(current)
                     control.Controls.AddAt(i, New LiteralControl(CType(current, LinkButton).Text))
                 ElseIf (TypeOf current Is ImageButton) Then
                     control.Controls.Remove(current)
                     control.Controls.AddAt(i, New LiteralControl(CType(current, ImageButton).AlternateText))
                 ElseIf (TypeOf current Is HyperLink) Then
                     control.Controls.Remove(current)
                     control.Controls.AddAt(i, New LiteralControl(CType(current, HyperLink).Text))
                 ElseIf (TypeOf current Is DropDownList) Then
                     control.Controls.Remove(current)
                     control.Controls.AddAt(i, New LiteralControl(CType(current, DropDownList).SelectedItem.Text))
                 ElseIf (TypeOf current Is CheckBox) Then
                     control.Controls.Remove(current)
                     control.Controls.AddAt(i, New LiteralControl(CType(current, CheckBox).Checked))
                     'TODO: Warning!!!, inline IF is not supported ?
                 End If
                 If current.HasControls Then
                     UtilClass.PrepareControlForExport(current)
                 End If
             End If
             i = (i + 1)
         Loop
     End Sub
dotnet-aspnet-webforms
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

YijingSun-MSFT avatar image
0 Votes"
YijingSun-MSFT answered YijingSun-MSFT commented

Hi @DavidChase-4918 ,
As far as I think,your export and add imagebutton events are right. But as far as I know,there are two problems of your codes:
1.You have to specify full path instead of relative path.
2.If Your image route format is right.
You could learn more about export images.

   Protected Sub ExportExcel(ByVal sender As Object, ByVal e As EventArgs)
             Image1.ImageUrl = Me.GetAbsoluteUrl(Image1.ImageUrl)
    
         Using sw As StringWriter = New StringWriter()
    
             Using hw As HtmlTextWriter = New HtmlTextWriter(sw)
                 Dim table As Table = New Table()
                 Dim row As TableRow = New TableRow()
                 row.Cells.Add(New TableCell())
                 row.Cells(0).Controls.Add(Image1)
                 table.Rows.Add(row)
                 table.RenderControl(hw)
                 Response.Clear()
                 Response.Buffer = True
                 Response.AddHeader("content-disposition", "attachment;filename=Images.xls")
                 Response.Charset = ""
                 Response.ContentType = "application/vnd.ms-excel"
                 Response.Write(sw.ToString())
                 Response.Flush()
                 Response.[End]()
             End Using
         End Using
     End Sub
    
     Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control)
     End Sub
    
     Private Function GetAbsoluteUrl(ByVal relativeUrl As String) As String
         relativeUrl = relativeUrl.Replace("~/", String.Empty)
         Dim splits As String() = Request.Url.AbsoluteUri.Split("/"c)
    
         If splits.Length >= 2 Then
             Dim url As String = splits(0) & "//"
    
             For i As Integer = 2 To splits.Length - 1 - 1
                 url += splits(i)
                 url += "/"
             Next
    
             Return url & relativeUrl
         End If
    
         Return relativeUrl
     End Function

Best regards,
Yijing Sun


If the answer is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our  documentation  to enable e-mail notifications if you want to receive the related email notification for this thread.

· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Sorry, I don't see where your code fits into mine. I am not exporting a single image but rather on one of the columns in many rows. I want the image to show up in the Excel cell.

0 Votes 0 ·

Hi @DavidChase-4918 ,
The sample I posted you that I only want to tell you how to convert relative path to full path. And if you have multiple images,you could for loop the gridview row.
Best regards,
Yijing Sun

0 Votes 0 ·

OK, but how does Excel know that it is an image? In my sample I was exporting the alternate text and I even tried the URL but both resulted in text displaying in Excel.

0 Votes 0 ·
Show more comments