Monday, May 12, 2014

Displaying HTML Tags in SSRS

SSRS doesn't have full support of html. Currently SSRS reports is supporting following basic HTML tags:
1) Hyperlinks: <A HREF>
2) Fonts: <FONT>
3) Header, style and block elements: <H {n}>, <DIV>, <SPAN>, <P>, <DIV>, <LI>, <HN>
4) Text format: <B>, <I>, <U>, <S>
5) List handling: <OL>, <UL>, <LI>
If you have above mentioned tags in your fields and variables then by following steps you can render them:
     1)  After dragging the column in SSRS Design Repot Page you can Right Click inside the column > Select Create Placeholder in Place holder Properties tab, select “HTML-Interpret HTML tags as styles” Radio Button.
 

If you need more tags - then it's not possible right now by this approach but in one of our client’s report we got to display HTML table tag. In this blog I'm trying to explain actual challenge faced with help of dummy projects. Hope this will help someone someday :)

We had followed different approach for this; we have converted whatever HTML data we were getting into filed into Image and then displayed that image into SSRS report. For HTML text to Image conversion we have used “HtmlRenderer.DLL” that can be found at following location http://htmlrenderer.codeplex.com/releases/view/100328. It’s Lightweight single dll and is 100% managed C# code without any external dependencies.  You may download the Demo application to explore HTML Renderer capabilities. I’ll be focusing only on Image displaying options with SSRS.

This can be achieved by following three approaches:

  • Saving Image into Database
  • Using Web Service
  • Using Custom Code in SSRS itself
I’ll discuss more about all approaches and provide sample test code herewith.
Saving Image into Database
For this approach While saving Data in DB for getting display into  report  we can convert associated HTML data as image and save as byte array into DB . Then SSRS report will Bind that binary data into image control.
For sample I’m assuming I have a table named “Testing_SSRSImages”, and it had a column named “Picture” which holds generated image as byte array. Now to render this image we can follow following steps:

  1.  We can query this in SSRS data set and get into one of the field.
  2.   Drag Image control into cell and configure Image Properties
a.       Select Image source as Database
b.      Select filed and MIME Type
  

For next two approaches too we’ll use same HtmlRenderer.DLL to convert HTML input to image. But by them we don’t need to store binary data into Database. If you don’t prefer to store images into DB then these two approaches can be proved helpful.
Using Web Service:
Let’s assume we have a WCF service which returns binary data with following contract

  [ServiceContract(Namespace = "http://localhost:56040/Service1")]
    public interface IService1
    {
        [OperationContract]
        byte[] GernrateImagefromHtml(string textToHTML);
    }


SSRS doesn’t have very good support for web services too. We have to use basic Http binding, with security mode none. Binding configuration will be as follows
<system.serviceModel>
              <behaviors>
                     <serviceBehaviors>
                           <behavior name="WcfService1.Service1Behavior">
                                  <serviceMetadata httpGetEnabled="true" />
                                  <serviceDebug includeExceptionDetailInFaults="true" />
                           </behavior>
                     </serviceBehaviors>
              </behaviors>
              <services>
                     <service behaviorConfiguration="WcfService1.Service1Behavior"
                      name="WcfService1.Service1">
                           <endpoint address=""
                           binding="basicHttpBinding"  bindingConfiguration="userHttps" contract="WcfService1.IService1">
                                  <identity>
                                         <dns value="localhost" />
                                  </identity>
                           </endpoint>
                           <endpoint address="mex"
                           binding="mexHttpBinding"
                           contract="IMetadataExchange" />
                     </service>
              </services>
              <bindings>
                     <basicHttpBinding>
                           <binding name="userHttps">
                                  <security mode="None" />
                           </binding>
                     </basicHttpBinding>
              </bindings>
              <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
       </system.serviceModel>




Then we have to follow following steps at SSRS level: 
  •   Configure data source type XML and Connection string will be service URL
  • Create Data set with above created data source. Now create text query to have SOAP request to service as follows
<Query>
<Method Name="GernrateImagefromHtml" Namespace="http://localhost:56040/Service1">
<Parameters>
<Parameter Name="textToHTML">1</Parameter>
</Parameters>
</Method>
<SoapAction>
http://localhost:56040/Service1/IService1/GernrateImagefromHtml
</SoapAction>
</Query>


The catch part is here namespace and SOAP action URL. If not configured properly then you have to invest lot of effort to find out any error.

  •   Now as in first approach we’ll have filed with binary Data that have to be mapped with Image control with same steps
Using Custom Code in SSRS itself
In SSRS we can write custom code using VB.net. For this approach I have created a class library in vb.net named “Html2ImageLib” its does same convert HTML data into Image and return as byte array.  
To use any external assembly into SSRS we have to register that into GAC with strong same and AllowPartiallyTrustedCallers settings.
  •   When ready with assembly then we have to add reference of that into RDL file. For that we have to click on report properties on body of report as follows
  •  In report properties add reference to your external assembly as follows:

 
  •  When add reference you need to provide class and instance name as follows:

  • In above screenshot Html2Image is class name in external assembly and I want SSRS to refer that class by txt2Image object.
  • Then we have add custom code to call our external assembly

  •   Next we have to set Image properties as follows
                  Data source:  Database
                  MIME Type:  Image/bmp
                  Value: will be an expression as follows




When all done then we are good to go… By using last approach we’ll have more control over code. But sometimes we get security exception when referring external assembly. 

[rsRuntimeErrorInExpression] The Value expression for the image ‘Image2’ contains an error: That assembly does not allow partially trusted callers.
[rsRuntimeErrorInExpression] The Value expression for the image ‘Image2’ contains an error: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
[rsInvalidExternalImageProperty] The value of the ImageData property for the image ‘Image2’ is “”, which is not a valid ImageData.
Preview complete -- 0 errors, 2 warnings


That can be removed by configuring “rsreportserver.config”. In my case this setting didn’t worked; and I’m not sure of the reason. When searched more found I need to add security rights into external assembly by using following lines
   Dim securityPermission As New SecurityPermission(PermissionState.Unrestricted)
        securityPermission.Assert()

All Set… Using above approaches we can extend HTML support in SSRS. In my case client has preferred service based approach.  Let me know if you have any question .



Courtesy: Random Web Images, MSDN, Several online resources 

9 comments:

  1. Hi!

    Can you please share the VB.net library you created for the second approach?

    Cheers!

    ReplyDelete
    Replies
    1. here is the code for VB.net library , Hope it helps

      Imports System

      Public Class Html2Image

      Public Function GetImageFromByte(ByVal textToHTML As String, ByVal sPath As String) As Byte()

      ConvertHtmlToImage(textToHTML, sPath)
      Return ReadFile(sPath)

      End Function

      Public Function ReadFile(ByVal sPath As String) As Byte()

      Dim data As Byte() = Nothing

      Dim fInfo As New System.IO.FileInfo(sPath)

      Dim numBytes As Long = fInfo.Length


      Dim fStream As New System.IO.FileStream(sPath, System.IO.FileMode.Open, System.IO.FileAccess.Read)

      Dim br As New System.IO.BinaryReader(fStream)

      data = br.ReadBytes(CInt(numBytes))

      Return data

      End Function

      Public Sub ConvertHtmlToImage(ByVal textToHTML As String, ByVal sPath As String)
      Dim m_Bitmap As New System.Drawing.Bitmap(400, 600)
      Dim point As New System.Drawing.PointF(0, 0)
      Dim maxSize As System.Drawing.SizeF = New System.Drawing.SizeF(500, 500)
      HtmlRenderer.HtmlRender.Render(System.Drawing.Graphics.FromImage(m_Bitmap), textToHTML, point, maxSize)

      m_Bitmap.Save(sPath, System.Drawing.Imaging.ImageFormat.Png)
      End Sub


      End Class

      Delete
  2. it is still very helpful

    ReplyDelete
  3. Hi, this is Virag. I have an exactly similar requirement and I had tried the solution. I am able to display the image in SSDT in development. But when I deployed to Report Server, images are not displayed. Getting a red cross instead of the image. I have added DLLs to GAC on the server. It is able to render HTML tags though and converting to image and displaying but wherever the IMG URL is there its not able to show it. It sounds like some kind of access issue.
    How you were able to deploy ?

    ReplyDelete

  4. Hi Manjul ,

    Finally I did it.
    In my case i have configure this two files.
    1)RSReportServer.config file
    Here i have added following lines.





    true


    2) rssrvpolicy.config
    and added FullTrust as code group here in each code group

    3) Added dlls to the following bin folder:
    C:\Program Files\Microsoft Power BI Report Server\PBIRS\ReportServer\bin

    I hope this will help any other visitor of this article in the future.

    Also one can read following article
    Reference:
    1) https://www.barcoderesource.com/SQLServerDataTools.shtml
    2)https://docs.microsoft.com/en-us/sql/reporting-services/report-server/rsreportserver-config-configuration-file?view=sql-server-ver15

    Thanks,
    Virag
    vnjagtap85@gmail.com

    ReplyDelete
  5. Hello Virag, how to decode html tables in SSRS. SSRS does not support more html tags.

    ReplyDelete
  6. Hi What is the the library name HtmlRenderer?

    ReplyDelete
    Replies
    1. Yes library name “HtmlRenderer.DLL” that can be found at following location http://htmlrenderer.codeplex.com/releases/view/100328

      Delete