Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multilanguage in SSRS

Is there a way to display/export english SSRS report in some other languages?

like image 830
sanjeev40084 Avatar asked Feb 17 '10 17:02

sanjeev40084


2 Answers

No, unfortunately, there's no easy way to do this :-( I've been trying to get this up and running myself, but in the end what I did was basically pass all the labels I want to have displayed on the report from the calling app (an ASP.NET app, in my case).

Another approach might be to store the text fragments in a SQL Server table, and add a datasource to your report which retrieves those text labels, and then bind them to the appropriate controls. I tried something like that but haven't been able to make it work for myself.

It's a pain that ASP.NET is so nicely internationalized with resources, but SSRS is still quite a messy affair when trying to make it multi-language aware :-(

like image 139
marc_s Avatar answered Oct 09 '22 12:10

marc_s


I managed to get multilanguage support, via .NET Resource files, by applying an interesting hack. There is an unused Property for every single Report Control, called ValueLocId. Using this property, you can specify the resource name to use for each control. The idea here is that you will be looping through your report definition, looking for controls that have the ValueLocID property set. If the property is set, replace the Text of that control with the Resource Text specified in the ValueLocID. So basically, the idea is this:

  1. Load the RDLC file in memory, as an XML file
  2. Traverse the XML file using XPath, looking for ValueLocID properties
  3. Replace the innerText of that XML node with the Resource specified in ValueLocID
  4. Load the ReportViewer control using the memory copy of the RDLC file.

See the function below, which will do exactly what I mentioned above.

Private Sub LocalizeReport()

    Dim xmlDoc As XmlDocument = New XmlDocument
    Dim asm As Reflection.Assembly = Reflection.Assembly.GetExecutingAssembly()
    'create in memory, a XML file from a embedded resource
    Dim xmlStream As Stream = asm.GetManifestResourceStream(ReportViewer1.LocalReport.ReportEmbeddedResource)

    Try
        'Load the RDLC file into a XML doc
        xmlDoc.Load(xmlStream)
    Catch e As Exception
        'HANDLE YOUR ERROR HERE
    End Try

    'Create an XmlNamespaceManager to resolve the default namespace
    Dim nsmgr As XmlNamespaceManager = New XmlNamespaceManager(xmlDoc.NameTable)
    nsmgr.AddNamespace("nm", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition")
    nsmgr.AddNamespace("rd", "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner")

    'IMPORTANT LINE BELOW
    'YOU WILL NEED TO SET THIS TO YOUR RESOURCE MANAGER, OTHERWISE NOTHING WILL WORK
    Dim rm As ResourceManager = New ResourceManager("Insurance.Subs.WinUI.Controls.Resources", asm)

    'Loop through each node in the XML file, that has the ValueLOCId property set.
    'Using this property as a workaround for localization support.  The value specified in this
    'property will determine what resource to use for translation.
    Dim node As XmlNode
    For Each node In xmlDoc.DocumentElement.SelectNodes(String.Format("//nm:{0}[@rd:LocID]", "Value"), nsmgr)  'XPath to LocID
        Dim nodeValue As String = node.InnerText
        If (String.IsNullOrEmpty(nodeValue) Or Not nodeValue.StartsWith("=")) Then
            Try
                Dim localizedValue As String = node.Attributes("rd:LocID").Value

                'Get the resource via string
                localizedValue = rm.GetString(localizedValue)
                If Not String.IsNullOrEmpty(localizedValue) Then
                    'Set the text value - via the retrieved information from resource file
                    node.InnerText = localizedValue
                End If

            Catch ex As Exception
                'handle error
            End Try
        End If
    Next

    ReportViewer1.LocalReport.ReportPath = String.Empty
    ReportViewer1.LocalReport.ReportEmbeddedResource = Nothing
    'Load the updated RDLC document into LocalReport object.
    Dim rdlcOutputStream As StringReader = New StringReader(xmlDoc.DocumentElement.OuterXml)
    Using rdlcOutputStream
        ReportViewer1.LocalReport.LoadReportDefinition(rdlcOutputStream)
    End Using

End Sub
like image 39
jgallant Avatar answered Oct 09 '22 13:10

jgallant