Reporting Services - Add a logo to the Report Manager

The SQL Server Reporting Services Report Manager is functional, but it's not very customizable. The ASPX pages just reference compiled assemblies, so the only real way to modify them is via CSS.

What makes that more difficult is that the SSRS HTML is poorly constructed so that the tags you'd most want to customize don't have Id's or Classes assigned. For instance, the most obvious customization anyone would want to make is to add a corporate logo, and there's no hook for that at all. The folder image is a simple <img> tag, nestled between two other spacer <img> tags, packed inside an unidentified <td>, and all those elements are written out in code1. The problem there is that there's no way, even with some descendant selector trickery, to target that folder image.

That's not entirely true, part 1:

IE7 adds support for some combinators (e.g. child, adjacent, first:sibling) which allow you to directly target elements without classes or id's. Why I'm not using that approach here:

  • IE6 doesn't support it.
  • IE7's support is kind of quirky - it sees HTML comments as page elements, for instance. That means it's difficult to write cross browser combinator based CSS rules.
  • Targeting deeply nested elements with combinators is pretty difficult.
  • Combinator based rules are inherently unstable, since any changes to the page's structure (including HTML comments, as mentioned above) can really mess up your page. Structure changes can cause your rule to be ignored or - much worse - point it at another page element.

That's not totally true, part 2:

You could replace the image files (C:\Program Files\Microsoft SQL Server\MSSQL.X\Reporting Services\ReportManager\images\48folderopen.jpg
as well as all the other files in that directory named 48*.jpg)2 with your corporate logo. Problems with that approach:

  • You're constrained to a 48x48 px jpg
  • Subsequent upgrades could overwrite it
  • Those images do serve some use - they change depending on the current function you're performing in the site.

Who needs an Upper Title, anyway?

I went for the next best target - the rather useless "upper title" - since it's a div which actually has a class (div.msrs-uppertitle)assigned. First, let's look at the style changes, then we'll talk about the different ways to add them.

.msrs-uppertitle { BACKGROUND: url(http://www.sitename.com/images/logo.gif) no-repeat; HEIGHT: 35px; WIDTH: 120px; TEXT-INDENT: -5000px; }

Some things to notice:

  1. We set a background image by URL. That will keep the reports up to date with our company logo as it may change in the future. Make sure to pick an image that's an appropriate size for that space.
  2. We set the background to no-repeat so it just displays once rather than tiling. That's handy even if the logo image has a border, since we don't have to be so precise on your height and width settings.
  3. We set a height and width which are large enough to display the logo. These should be just larger than your image size; you can just see via trial and error what looks best. This is one of those times where on the fly CSS editing tools like the IE DevToolbar or the Firefox Web Developer extension come in really handy.
  4. Now we need to get rid of the site title. I didn't want to mess with trying to blank it out in the SSRS Site Settings since it might be useful elsewhere, or someone might fill it in without knowing that it would conflict with the logo. The easiest solution is to use the Phark Image Replacement technique and hide the text by setting the indent to -5000px.

Done and done.

Oh, wait. I said I'd be talking about where to add this style, didn't I? A few options:

  1. Edit ReportingServices.css (in the C:\Program Files\Microsoft SQL Server\MSSQL.3\Reporting Services\ReportManager\Styles folder).
  2. Use another stylesheet - method 1: change the HTMLViewerStyleSheet parameter in RSReportServer.config
  3. Use another stylesheet - method 2: specify a stylesheet in rc:StyleSheet parameter of the report url:
    http://localhost/reportserver?/AdventureWorksSampleReports/Product+Line+Sales&rs:Command=Render&rc:Stylesheet=MyStyleSheet

I went with a variation of option 1 - I edited ReportingServices.css, but just to add an import statement that points to another CSS file where I'll put all my Reporting Services CSS customizations:

  1. Add the following to the top of ReportingServices.css:
    @import url(customizations.css);
  2. Save the block of CSS (the bit that starts with ".msrs-uppertitle") to a file called customizations.css to the same folder as ReportingServices.css. You might want to add other customizations to it while you're at it, like this CSS fix for Firefox.

That's it! We're done!

Great, but the logo should link to the home page of our intranet!

What!? Feature creep! Version 2!

Oh, okay. It's not easy, though...

Changing style isn't a piece of cake, but at least there's a supported hook for it. You can't add a link via CSS, though. CSS2 allows for some limited content generation, but it doesn't support adding links; even if it did we'd be out of luck because IE7 doesn't support it.

Bill Vaughn and Peter Blackburn proposed a solution using DHTML Behaviors. That's a pretty slick workaround - behaviors allow you to tie Javascript functionality to DOM elements in CSS. Unfortunately, only IE supports behaviors. Plus, if you're going to hack Javascript, why not edit the ReportingServices.js file...3

C:\Program Files\Microsoft SQL Server\MSSQL.n\Reporting Services\ReportManager\js\ReportingServices.js

There it is... the fabled treasure... a way to modify the content of the Reporting Services Manager...

I added the following code to the top of the JS file (after backing it up, of course):

addLoadEvent(SetLogoUrl); function addLoadEvent(fn) { if (window.addEventListener) window.addEventListener('load', fn, false) else if (window.attachEvent) window.attachEvent('onload', fn); } function SetLogoUrl() { var header = document.getElementById('ui_sharedArea'); if (!header) return; var headerDivs = header.getElementsByTagName('div'); for (var i=0;i<headerDivs.length;i++) { if(headerDivs[i].className == 'msrs-uppertitle') { headerDivs[i].onclick = new Function('top.location="/"'); headerDivs[i].style.cursor = 'pointer'; //headerDivs[i].style.backgroundImage = 'url(http://images.slashdot.org/topics/topiccommunications.gif)'; //headerDivs[i].style.backgroundRepeat = 'no-repeat'; //headerDivs[i].style.width = '96px'; //headerDivs[i].style.height = '62px'; } } }

 

Let's talk about it:

  1. That addLoadEvent business is there because we can't modify the page until it has finished loading, but this script is included at the top of the page. A less sophisticated solution is to set a timeout to call SetLogoUrl, but addLoadEvent leverages the built in event model to call the function after the page has finished loading. IE uses attachEvent, while everyone else uses addEventListener, so we'll include some logic to make sure the right one gets called.
  2. SetLogoUrl's job is to modify the Upper Title DIV. This would be easier if that DIV had an ID assigned, since Javascript doesn't have built in support for retrieving an element by class name. Most sample code which returns an element by class just iterates all elements in the DOM looking for a class name match, but since we know a bit about the page structure we can be a little more efficient. We narrow the search by grabbing the nearest parent element with an ID assigned and only searching through its children.
  3. Once we've got our DIV, we can just set the onclick behavior to navigate to the correct URL. We'll need to change the cursor to indicate that it's a link, too.

Hey, since we're messing with that DIV, why not just change the image in Javascript and simplify things? Well, I've left some commented code there to get you started if that's what you want to do, but I think it's better to keep the image modification in CSS.

Why? Well, there are a few good reasons. The biggest reason is that the Javascript doesn't execute until the page has finished loading, so the original DIV text is displayed, then changes to the logo. Ugh. Plus, from a maintenance and architectural perspective, it's a much better practice to keep your presentation information in CSS and your behaviors in Javascript.

And that's it.

But, can we change the navigation to use WPF/E with Ajax and pull in some Google Analytics?

No.


1 reflector://Microsoft.ReportingServices.UI.SharedArea.InitTitleArea()

2 Reporting Service installs into different directories depending on the order you install SQL Server services. A default installation will put Reporting Services in \Program Files\Microsoft SQL Server\MSSQL.3\Reporting Services, but that MSSQL.3 folder may be different on your machine.

3 I actually stumbled across the HTC technique after I'd finished making this work as a Javascript include.

29 Comments

  • Hi Jon

    It's one in the morning in ireland and i have spent hours figuring out how to add a logo with a link to report manager, i really was pulling my hair out, that is until i came across your article, it was a godsend, thanks a million for script. it works perfectly.

  • Does anyone know if it is legally legit to use reflector to decompile the Report Manager DLLs, modify as needed, recompile and deploy?

    I've read Microsoft's claim:

    "You can customize Report Manager in very limited ways. You can modify the application title on the Site Settings page. If you are a Web developer, you can modify the style sheets that contain the style information used by Report Manager. Because Report Manager is not specifically designed to support customization, you must thoroughly test any modification that you make. If you find that Report Manager does not meet your needs, you can develop a custom report viewer or configure SharePoint Web parts to find and view reports in a SharePoint site."

    I've also read the law regarding decompilation, and I'm still not entirely clear.

  • Very useful post - thanks alot!

    you could also try this trick to hide the ugly 'context' icon in the top left...

    /* Upper title on the page - set position to absolute and configure the top-left positions */
    .msrs-uppertitle
    {
    position:absolute;
    top: 0px;
    left: 0px;
    background: url(url to your icon);
    height: 66px;
    width: 182px;
    text-indent: -5000px;
    }

    /* adjust the height of the containing row to fit the image in */
    #ui_sharedArea
    {
    height: 80px;
    }

    not tested in browsers other than IE6/7 though

    Steve

  • Can somebody tell me how do i customize my report names (ABC) to appear instead of the ugly Report Manager.

  • No, i meant, just like using external application like c# we can title(IE)the report name from Report Manager to customized name (ABC). Is there a way to customize the title of IE just by SSRS.

  • I am creating a aspx page. From that page i am going to call Report Manager.I want to show the customize report manager only launch from my application. is it possible? Please healp me.

  • We decided it was easier in the long run to download and install Windows Sharepoint Servers 3.0 and install that on the report server, then switch reporting services into Sharepoint Intergrated mode. That gave us all the functionality of Reporting Services but also the fully customisable interface of Sharepoint. Works well for us!

  • I note the comment about switching to Deep Integrated mode to use fully customisable interface of SharePoint. However has anyone successfully managed to pass parameters via query string into the Deep Integrated Report Viewer? It looks like to get parameter passing to work this way you still have to use the native report viewer, which is not exactly the sharepoint look and feel! I may be missing something though, does anyone out there have the missing piece of this jigsaw available yet?

  • i want to know how to connect the report manager with reporting services and explain fully about the installation of sql reporting services in sqlserver2005 express edition

  • Thsnks for this. Have linked you freom my blog

    Rich D

  • great article!!It's help me so much..

  • Boutique de vente en ligne d’electromenager et high-tech

  • Followed the recipe for RS2008 but nothing doing... No change in appearance on the home page...

    Have you had a chance to see if RS2008 can be overridden? The css' appear to be in Program Files\Microsoft SQL Server\MSRS10.MSSQLSERVER\Reporting Services\ReportManager\Styles

    Thanks for what promised to be a neat customization - shame about RS2008's resistance to change...

  • hm. thanks for post!

  • I tried this, but unless I replace 48folderopen.jpg with my logo, it doesn't work.

  • а все таки: восхитительно!! а82ч

  • I agree with sweelyhosergy..

  • I have followed the instructions here and my company logo still does not appear on my Report Manager

  • I am really enjoying the theme/design of your weblog. Do you ever run into any web browser compatibility issues?
    A handful of my blog visitors have complained about my
    website not operating correctly in Explorer but looks great in Opera.
    Do you have any ideas to help fix this issue?

  • I think that everything composed was actually very logical.
    But, what about this? suppose you were to create
    a killer title? I mean, I don't wish to tell you how to run your website, however suppose you added a headline that makes people want more? I mean Reporting Services - Add a logo to the Report Manager - Jon Galloway is a little plain. You should glance at Yahoo's front page and
    note how they create article headlines to get viewers interested.
    You might add a video or a related pic or two to grab readers
    excited about everything've got to say. Just my opinion, it could make your website a little livelier.

  • exopo tony romo jersey
    hevyh desean jackson jersey
    sbtzt champ bailey jersey
    sxmyw ben roethlisberger jersey
    dyhtr jason pierre paul jersey

  • These are in fact great ideas in regarding blogging.
    You have touched some pleasant points here.
    Any way keep up wrinting.

  • Unquestionably believe that which you stated. Your favorite reason appeared to be on the web the easiest thing to be aware of.
    I say to you, I definitely get annoyed while people consider worries
    that they plainly don't know about. You managed to hit the nail upon the top as well as defined out the whole thing without having side effect , people could take a signal. Will probably be back to get more. Thanks

  • I feel that is one of the such a lot important information for me.
    And i'm satisfied studying your article. However wanna commentary on some normal issues, The site style is ideal, the articles is in reality great : D. Excellent activity, cheers

  • I read this article completely about the resemblance of most up-to-date and earlier technologies, it's awesome article.

  • I comment each time I appreciate a post on a website or I have something
    to contribute to the conversation. It is caused by the passion displayed
    in the article I looked at. And on this post Reporting Services - Add a logo
    to the Report Manager - Jon Galloway. I was actually excited
    enough to drop a comment :) I do have a few questions for you if you don't mind. Could it be just me or do a few of these responses look as if they are coming from brain dead folks? :-P And, if you are posting on additional online sites, I'd like to keep up with everything new you have to post.
    Would you list the complete urls of your public pages like
    your twitter feed, Facebook page or linkedin profile?

  • For the reason that the admin of this site is working, no doubt
    very shortly it will be renowned, due to its quality contents.

  • Ringlets differ in length of life and place of growth. Longest-living hair on his fore-part - to 4 or even 10 years, but the hair high the armpits, eyebrows and eyelashes - on the contrary 3-4 months. Japanese old lady Hiroko Yamaske took 18 years to reach its band length of 2.6 m common extension of trifle per date - involving 0.35-0.4 mm, and at end of day they bourgeon below par, and preferably in the evening. On the chairlady, beard and underarm trifle grows more actively than in the get of the body.

  • O y眉zden giysi buldu臒umuzda 莽ok mutlu olduk.

    Minerals include calcium, chloride, copper, iodine magnesium, phosphorus, potassium, zinc, sodium and selenium..

    The Royals then joined the Queen and 700 members of the livery companies, the original trade associations, at a grand lunch in Westminster Hall.

    Reservations would be recommended for most restaurants on the weekends.

    In addition, Timberland High Top Boots may also consider the future development of children's clothing market.

Comments have been disabled for this content.