SSRS 2008 R2 - SSRS 2012 - ReportViewer: Raporty są puste w Safari i Chrome

84

Przeprowadziłem migrację naszych usług raportowania z wersji 2008 do innej wersji serwera 2008 R2. W wersji 2008 raporty działają poprawnie w przeglądarce Safari. W nowej wersji 2008 R2 raporty w ogóle się nie pojawiają. Widzę tylko sekcję parametrów, a raport jest pusty. To samo w Chrome. Według Microsoft Safari jest obsługiwany, jeśli jest ograniczony. Raporty nie są skomplikowane. W rzeczywistości utworzyłem raport, który zawierał tylko wiersz, aby sprawdzić, czy pojawi się w Safari, ale nie, ten raport jest również całkowicie pusty. Czy ktoś udostępnił raporty SSRS w przeglądarce Safari? Czy muszę majstrować przy jakimś ustawieniu konfiguracyjnym?

Anita C
źródło
duplicate: stackoverflow.com/questions/5428017/…
Tim Partridge

Odpowiedzi:

109

Ostateczne rozwiązanie (działa również w SSRS 2012!)

Dołącz następujący skrypt do następującego pliku (na serwerze SSRS)
C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\ReportManager\js\ReportingServices.js

function pageLoad() {    
    var element = document.getElementById("ctl31_ctl10");
    if (element) 
    {
        element.style.overflow = "visible"; 
    }
}

Uwaga : jak zauważył Azzlak, nazwa div nie zawsze ctl31_ctl10. W przypadku SQL 2012 wypróbuj, ctl32_ctl09aw przypadku 2008 R2 wypróbuj ctl31_ctl09. Jeśli to rozwiązanie nie działa, spójrz na kod HTML w przeglądarce, aby sprawdzić, czy skrypt działał poprawnie, zmieniając overflow:autowłaściwość na overflow:visible.


Rozwiązanie dla kontroli ReportViewer

Wstaw na .aspxstronę (lub do połączonego .csspliku, jeśli jest dostępny) tę linię stylu

#reportViewer_ctl09 {
  overflow:visible !important;
 }

Powód

Chrome i Safari renderują się overflow:autoinaczej niż IE.

HTML SSRS to QuirksMode HTML i zależy od błędów IE 5.5. Przeglądarki inne niż IE nie mają trybu dziwnego IE i dlatego poprawnie renderują kod HTML

Strona HTML generowana przez raporty SSRS 2008 R2 zawiera, divktóry ma overflow:autostyl i zamienia raport w niewidoczny raport.

<div id="ctl31_ctl10" style="height:100%;width:100%;overflow:auto;position:relative;">

Widzę raporty dotyczące Chrome ręcznie zmienić overflow:autosię overflow:visiblew wytworzonym za pomocą strony internetowej Chrome Dev Tools ( F12).


Uwielbiam rozwiązanie Tima , jest łatwe i działa.

Ale nadal jest problem: za każdym razem, gdy użytkownik zmienia parametry (moje raporty używają parametrów!) AJAX odświeża div, przepełnienie: auto tag jest przepisywane i żaden skrypt go nie zmienia.

Ten szczegół techniczny wyjaśnia, na czym polega problem:

Dzieje się tak, ponieważ na stronie zbudowanej przy użyciu paneli AJAX tylko panele AJAX zmieniają swój stan, bez odświeżania całej strony. W rezultacie OnLoadzdarzenia zastosowane w <body>tagu są uruchamiane tylko raz: przy pierwszym wczytaniu strony. Potem zmiana któregokolwiek z paneli AJAX nie będzie już powodować tych zdarzeń.

Użytkownik einarq zasugerował takie rozwiązanie :

Inną opcją jest zmiana nazwy funkcji na pageLoad. Wszelkie funkcje o tej nazwie będą wywoływane automatycznie przez plik asp.net ajax, jeśli istnieje na stronie, również po każdej częściowej aktualizacji. Jeśli to zrobisz, możesz również usunąć atrybut onload z tagu body

Tak napisał ulepszony skrypt, który jest pokazany w rozwiązaniu.

Emanuele Greco
źródło
1
Zmieniłem funkcję page_load na pageLoad, aby uruchomić skrypt. W przeciwnym razie wydaje się, że rozwiązuje problemy z renderowaniem w Chrome 13. Niestety, podstawowe uwierzytelnianie w SSRS nie działa z Safari 5.1, więc nie mogę tam zweryfikować.
kermatt
Powód jest zły. Prawdziwym powodem jest to, że SSRS HTML to QuirksMode HTML i zależy od błędów IE 5.5. Przeglądarki inne niż IE nie mają trybu dziwnego IE i dlatego prawidłowo renderują kod HTML. W przeglądarkach, które nie emulują błędów IE 5.5 w swoim QuirksMode, brakuje ustawienia szerokości tabeli ... Nawiasem mówiąc, dotyczy to również IE 10, ponieważ ma nowy domyślny tryb quirksmode.
Stefan Steiger
8
Działa świetnie. Ale w przypadku programu SQL Server 2012 naruszający identyfikator div to ctl32_ctl09.
azzlack
3
zamiast szukać identyfikatora ctl32_ctl09 lub innego wygenerowanego identyfikatora, spróbuj: document.querySelector ("[id ^ = VisibleReportContent]"). parentNode;
Para
1
@JustinMangum - użycie querySelector nie powiedzie się w IE w widoku zgodności, który prawie na pewno jest włączony dla witryn intranetowych SSRS. Objawem jest to, że okno dialogowe Ładowanie nigdy się nie zamknie, więc użytkownicy nie będą mogli wyświetlić żadnego raportu.
Mike
27

Po prostu dołącz, SizeToReportContent="true"jak pokazano poniżej

<rsweb:ReportViewer ID="ReportViewer1" runat="server" SizeToReportContent="True"...
Deepak
źródło
4
Nie wiem, dlaczego nie jest to akceptowane rozwiązanie, ponieważ a) działa dobrze i b) wydaje się, że jest to rozwiązanie wbudowane. To nie jest hack, aby przeglądarka raportów działała poprawnie. Nie chodzi o to, że jest coś złego w hakowaniu ReportViewer, aby działał. Wygląda na to, że cała przeglądarka raportów jest na wielkim haku.
Raif
3
Czy to rozwiązanie nie dotyczy tylko osadzania formantu ReportViewer w aplikacji? Jeśli dotyczy to Menedżera raportów i raportów uruchamianych z adresu URL serwera raportów, należy określić, gdzie należy uwzględnić tę zmianę.
Zarejestrowany użytkownik
2
Czy odnosisz się do następującego wiersza w \ SQL \ MSRS11.MSSQLSERVER \ Reporting Services \ ReportServer \ Pages \ ReportViewer.aspx: <RS: ReportViewerHost ID = "ReportViewerControl" runat = "server" />
Zarejestrowany użytkownik
1
Może to działać dobrze, ale jeśli masz dużo obrazów (wskaźników / wykresów przebiegu w czasie) w raporcie, okropnie wydłuży to czas renderowania.
Trubs
1
To nie działa podczas modyfikowania ReportViewer.aspx w SSRS 2012.
Keith
23

Używam Chrome w wersji 21 z SQL 2008 R2 SP1 i żadna z powyższych poprawek nie zadziałała. Poniżej znajduje się kod, który zadziałał, podobnie jak w przypadku innych odpowiedzi, które dodałem ten fragment kodu, aby dołączyć do „C: \ Program Files \ Microsoft SQL Server \ MSRS10_50.MSSQLSERVER \ Reporting Services \ ReportManager \ js \ ReportingServices.js” (na serwer SSRS):

//Fix to allow Chrome to display SSRS Reports
function pageLoad() { 
    var element = document.getElementById("ctl31_ctl09");
    if (element) 
    {
        element.style.overflow = "visible";         
    } 
}
Michael Brown
źródło
1
To rozwiązanie bardzo dobrze sprawdza się w naszym środowisku. Dzięki Mike
Vince Perta
14

To znany problem . Problem polega na tym, że znacznik DIV ma styl „overflow: auto”, który najwyraźniej nie jest dobrze zaimplementowany w WebKit, używanym przez Safari i Chrome (patrz odpowiedź Emanuele Greco). Nie wiedziałem, jak skorzystać z sugestii Emanuele, aby użyć elementu RS: ReportViewerHost, ale rozwiązałem to za pomocą JavaScript.

Problem

wprowadź opis obrazu tutaj

Rozwiązanie

Ponieważ „overflow: auto” jest określony w atrybucie stylu elementu div o identyfikatorze „ctl31_ctl10”, nie możemy go zastąpić w pliku arkusza stylów, więc zdecydowałem się na JavaScript. Dodałem następujący kod do „C: \ Program Files \ Microsoft SQL Server \ MSRS10_50.MSSQLSERVER \ Reporting Services \ ReportManager \ js \ ReportingServices.js”

function FixSafari()
{    
    var element = document.getElementById("ctl31_ctl10");
    if (element) 
    {
        element.style.overflow = "visible";  //default overflow value
    }
}

// Code from http://stackoverflow.com/questions/9434/how-do-i-add-an-additional-window-onload-event-in-javascript
if (window.addEventListener) // W3C standard
{
    window.addEventListener('load', FixSafari, false); // NB **not** 'onload'
} 
else if (window.attachEvent) // Microsoft
{
    window.attachEvent('onload', FixSafari);
}

Uwaga

Wydaje się, że istnieje rozwiązanie dla SSRS 2005 , którego nie próbowałem, ale nie sądzę, aby miało ono zastosowanie do SSRS 2008, ponieważ nie mogę znaleźć klasy „DocMapAndReportFrame”.

Tim Partridge
źródło
2
Jest jedna rzecz, której nie rozumiem. Jeśli zastosujesz funkcję kodu FixSari w \ ReportingServices.js, a następnie wykonasz kod, aby wyświetlić raport w SSRS, gdzie zastosujesz funkcję do wykonania kodu metody źródłowej dla FixSafari? Jeśli dobrze rozumiem, generowany jest oryginalny kod ReportingServices.js i na końcu uruchamiasz kod FixSafari?
What'sUP,
12

Moje rozwiązanie oparte na powyższych pomysłach.

function pageLoad() {
    var element = document.querySelector('table[id*=_fixedTable] > tbody > tr:last-child > td:last-child > div');
    if (element) {
        element.style.overflow = "visible";
    } 
}

Nie jest ograniczone do określonego identyfikatora, a ponadto nie musisz dołączać żadnej innej biblioteki, takiej jak jQuery.

Jim Bauwens
źródło
Ale elementy, na które wszyscy inni kierują, takie jak ctl31_ctl10 i jego warianty, niekoniecznie mają w sobie _fixedTable. Czy coś mi brakuje?
Baodad
@Baodad - powyższe rozwiązanie wykorzystuje selektor elementu podrzędnego, aby znaleźć prawidłowy element div. Rozpoczyna się od pozycji znajdującej się wyżej w łańcuchu z bardziej statycznym atrybutem id, a następnie prowadzi dzieci w dół drzewa do żądanego elementu div. Wolałbym, aby używał bardziej opisowej, mniej przeciążonej nazwy zmiennej, ale jest to doskonałe rozwiązanie. Sugerowana nazwa: reportPayloadElement.
Brian Swift
11

Oto rozwiązanie, którego użyłem dla programu Report Server 2008 R2

Powinien działać niezależnie od tego, co serwer raportów wyprowadzi do użycia w swoim atrybucie „id” tabeli. Myślę, że nie zawsze można założyć, że będzie to „ctl31_fixedTable”

Użyłem kombinacji powyższych sugestii i kilku sposobów na dynamiczne ładowanie bibliotek jquery na stronę z pliku javascript znajdującego się tutaj

Na serwerze przejdź do katalogu: C: \ Program Files \ Microsoft SQL Server \ MSRS10_50.MSSQLSERVER \ Reporting Services \ ReportManager \ js

Skopiuj bibliotekę jquery jquery-1.6.2.min.js do katalogu

Utwórz kopię zapasową pliku ReportingServices.js Edytuj plik. I dołącz to na dole:

var jQueryScriptOutputted = false;
function initJQuery() {

    //if the jQuery object isn't available
    if (typeof(jQuery) == 'undefined') {


        if (! jQueryScriptOutputted) {
            //only output the script once..
            jQueryScriptOutputted = true;

            //output the script 
            document.write("<scr" + "ipt type=\"text/javascript\" src=\"../js/jquery-1.6.2.min.js\"></scr" + "ipt>");
         }
        setTimeout("initJQuery()", 50);
    } else {

        $(function() {     

        // Bug-fix on Chrome and Safari etc (webkit)
        if ($.browser.webkit) {

            // Start timer to make sure overflow is set to visible
             setInterval(function () {
                var div = $('table[id*=_fixedTable] > tbody > tr:last > td:last > div')

                div.css('overflow', 'visible');
            }, 1000);
        }

        });
    }        
}

initJQuery();
Eric Weiss
źródło
Jedno pytanie, czy jeśli na stronie znajduje się więcej niż jedna tabela raportu, czy nie spowoduje to wielokrotnego ładowania formantów? Jeśli tak, to pierwszą linię można zmienić na: var jQueryScriptOutputted = ((typeof (jQueryScriptOutputted) == 'undefined')? False: true);
rmcsharry
4

Możesz to łatwo naprawić za pomocą jQuery - i trochę brzydkiego hacka :-)

Mam stronę asp.net z kontrolką użytkownika ReportViewer.

 <rsweb:ReportViewer ID="ReportViewer1" runat="server"...

W zdarzeniu gotowości dokumentu uruchamiam licznik czasu i szukam elementu, który wymaga naprawy przepełnienia (jak w poprzednich postach):

 <script type="text/javascript">
    $(function () {
        // Bug-fix on Chrome and Safari etc (webkit)
        if ($.browser.webkit) {
            // Start timer to make sure overflow is set to visible
             setInterval(function () {
                var div = $('#<%=ReportViewer1.ClientID %>_fixedTable > tbody > tr:last > td:last > div')
                div.css('overflow', 'visible');
            }, 1000);
        }
    });
</script>

Lepsze niż zakładanie, że ma określony identyfikator. Możesz ustawić timer według własnego uznania. Ustawiłem tutaj na 1000 ms.

henebb
źródło
3

Do Twojej wiadomości - żadne z powyższych nie zadziałało dla mnie w 2012 SP1 ... prostym rozwiązaniem było osadzenie poświadczeń w udostępnionym źródle danych, a następnie poinformowanie Safari, aby zaufała witrynie serwera SSRS. Wtedy zadziałało świetnie! Dni szukania rzekomych rozwiązań, takich jak powyżej, tylko po to, aby dowiedzieć się, że zintegrowane zabezpieczenia nie będą działać niezawodnie w Safari - musisz zadzierać z pękiem kluczy na komputerze Mac, a potem nadal nie będzie działać niezawodnie.

Gary Melhaff
źródło
2

Rozwiązanie dostarczone przez Emanuele sprawdziło się dla mnie. Mogłem zobaczyć raport, gdy uzyskałem do niego dostęp bezpośrednio z serwera, ale kiedy użyłem formantu ReportViewer na mojej stronie aspx, nie mogłem zobaczyć raportu. Po sprawdzeniu renderowanego kodu HTML znalazłem element div o identyfikatorze „ReportViewerGeneral_ctl09” ( ReportViewerGeneral to identyfikator serwera kontrolki przeglądarki raportów), dla którego właściwość przepełnienia została ustawiona na auto.

<div id="ReportViewerGeneral_ctl09" style="height: 100%; width: 100%; overflow: auto; position: relative; ">...</div>

Użyłem procedury wyjaśnionej przez Emanuele, aby zmienić to na widoczne w następujący sposób:

function pageLoad() {
    var element = document.getElementById("ReportViewerGeneral_ctl09");

    if (element) {
        element.style.overflow = "visible";
    }
}
Samir K
źródło
2

Użyłem tego. Dodaj odwołanie do skryptu do jquery na stronie Report.aspx. Użyj poniższego, aby połączyć JQuery ze zdarzeniami Microsoft. Wykorzystałem trochę sugestii Erica do ustawienia przepełnienia.

$(document).ready(function () {
    if (navigator.userAgent.toLowerCase().indexOf("webkit") >= 0) {        
        Sys.Application.add_init(function () {
            var prm = Sys.WebForms.PageRequestManager.getInstance();
            if (!prm.get_isInAsyncPostBack()) {
                prm.add_endRequest(function () {
                    var divs = $('table[id*=_fixedTable] > tbody > tr:last > td:last > div')
                    divs.each(function (idx, element) {
                        $(element).css('overflow', 'visible');
                    });
                });
            }
        });
    }
});
MeyC
źródło