SSRS 2008 R2 - SSRS 2012 - ReportViewer: i rapporti sono vuoti in Safari e Chrome


84

Ho migrato i nostri servizi di reporting dalla versione 2008 a un'altra versione del server 2008 R2. Nella versione 2008 i rapporti funzionano bene su Safari. La nuova versione 2008 R2 i rapporti non vengono visualizzati affatto. Tutto quello che vedo è la sezione dei parametri e quindi il rapporto è vuoto. Lo stesso in Chrome. Secondo Microsoft Safari è supportato se in modo limitato. Le relazioni non sono complesse. In effetti ho creato un rapporto che conteneva solo una riga per vedere se sarebbe stato visualizzato in Safari ma no, anche quel rapporto è completamente vuoto. Qualcuno ha reso i report SSRS visualizzabili su Safari? Devo fare confusione con una sorta di impostazione di configurazione?


Risposte:


109

Soluzione definitiva (funziona anche in SSRS 2012!)

Aggiungi lo script seguente al file seguente (sul server 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"; 
    }
}

Nota : come notato azzlak, il nome del div non è sempre ctl31_ctl10. Per SQL 2012 provare ctl32_ctl09e per 2008 R2 provare ctl31_ctl09. Se questa soluzione non funziona, guarda l'HTML dal tuo browser per vedere se lo script ha funzionato correttamente cambiando la overflow:autoproprietà in overflow:visible.


Soluzione per il controllo ReportViewer

Inserire nella .aspxpagina (o in un .cssfile collegato , se disponibile) questa linea di stile

#reportViewer_ctl09 {
  overflow:visible !important;
 }

Motivo

Chrome e Safari rendono il rendering overflow:autoin modo diverso rispetto a IE.

SSRS HTML è QuirksMode HTML e dipende dai bug di IE 5.5. I browser non IE non hanno la modalità bizzarra di IE e quindi visualizzano correttamente l'HTML

La pagina HTML prodotta dai report SSRS 2008 R2 contiene un divche ha uno overflow:autostile e trasforma il report in un report invisibile.

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

Posso visualizzare i rapporti su Chrome passando manualmente overflow:autoa overflow:visiblenella pagina web prodotta utilizzando gli strumenti di sviluppo di Chrome ( F12).


Adoro la soluzione di Tim , è facile e funzionante.

Ma c'è ancora un problema: ogni volta che l'utente modifica i parametri (i miei rapporti usano parametri!) AJAX aggiorna il div, il tag overflow: auto viene riscritto e nessuno script lo cambia.

Questo dettaglio della nota tecnica spiega qual è il problema:

Ciò accade perché in una pagina costruita con pannelli AJAX, solo i pannelli AJAX cambiano il loro stato, senza aggiornare l'intera pagina. Di conseguenza, gli OnLoadeventi che hai applicato al <body>tag vengono attivati ​​solo una volta: la prima volta che la tua pagina viene caricata. Dopodiché, la modifica di uno qualsiasi dei pannelli AJAX non attiverà più questi eventi.

L'utente einarq ha suggerito questa soluzione :

Un'altra opzione è rinominare la funzione in pageLoad. Eventuali funzioni con questo nome verranno chiamate automaticamente da asp.net ajax se presente nella pagina, anche dopo ogni aggiornamento parziale. Se lo fai, puoi anche rimuovere l'attributo onload dal tag body

Così ha scritto lo script migliorato mostrato nella soluzione.


1
Ho modificato la funzione page_load in pageLoad per attivare lo script. Altrimenti, sembra risolvere i problemi di rendering in Chrome 13. Sfortunatamente l'autenticazione di base in SSRS non sembra funzionare con Safari 5.1, quindi non posso verificare lì.
kermatt

Il motivo è SBAGLIATO. Il vero motivo è che SSRS HTML è QuirksMode HTML e dipende dai bug di IE 5.5. I browser non IE non hanno il quirksmode di IE e quindi visualizzano correttamente l'HTML. Per i browser che non emulano i bug di IE 5.5 nel loro QuirksMode, manca l'impostazione della larghezza della tabella ... Questo vale anche per IE 10, dato che ha una nuova modalità quirksmode predefinita.
Stefan Steiger

8
Funziona perfettamente. Ma per SQL Server 2012, l'id div incriminato è ctl32_ctl09.
azzlack

3
invece di cercare id ctl32_ctl09 o qualsiasi altra cosa generata, prova: document.querySelector ("[id ^ = VisibleReportContent]"). parentNode;
Para

1
@JustinMangum: l'utilizzo di querySelector fallirà in IE in Visualizzazione Compatibilità, che è quasi certamente abilitata per i siti SSRS intranet. Il sintomo è che la finestra di dialogo di caricamento non si chiuderà mai, quindi gli utenti non saranno in grado di visualizzare alcun rapporto.
Mike

27

Basta includere SizeToReportContent="true"come mostrato di seguito

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

4
Non so perché questa non sia la soluzione accettata in quanto a) funziona bene, eb) sembra essere la soluzione integrata. Non è un trucco per far funzionare correttamente il visualizzatore di report. Non che ci sia qualcosa di sbagliato nell'hacking di ReportViewer per farlo funzionare. Sembra che l'intero visualizzatore di report sia su un grosso problema.
Raif

3
Questa soluzione non si applica solo all'incorporamento del controllo ReportViewer in un'applicazione? Se ciò si applica a Report Manager e i rapporti vengono eseguiti dall'URL ReportServer, specificare dove è necessario includere questa modifica.
Utente registrato il

2
Ti riferisci alla seguente riga in \ SQL \ MSRS11.MSSQLSERVER \ Reporting Services \ ReportServer \ Pages \ ReportViewer.aspx: <RS: ReportViewerHost ID = "ReportViewerControl" runat = "server" />
Utente registrato

1
Esso può funzionare bene, ma se avete un sacco di immagini (indicatori / sparkline) su una relazione che soffiare il tempo di rendering fuori atrocemente.
Trubs

1
Questo non funziona quando si modifica ReportViewer.aspx in SSRS 2012.
Keith

23

Sto usando Chrome versione 21 con SQL 2008 R2 SP1 e nessuna delle correzioni di cui sopra ha funzionato per me. Di seguito è riportato il codice che ha funzionato, poiché con le altre risposte ho aggiunto questo bit di codice da aggiungere a "C: \ Program Files \ Microsoft SQL Server \ MSRS10_50.MSSQLSERVER \ Reporting Services \ ReportManager \ js \ ReportingServices.js" (su il server SSRS):

//Fix to allow Chrome to display SSRS Reports
function pageLoad() { 
    var element = document.getElementById("ctl31_ctl09");
    if (element) 
    {
        element.style.overflow = "visible";         
    } 
}

1
Questa soluzione funziona molto bene nel nostro ambiente. Grazie Mike
Vince Perta

14

Questo è un problema noto . Il problema è che un tag div ha lo stile "overflow: auto" che apparentemente non è implementato bene con WebKit che viene utilizzato da Safari e Chrome (vedi risposta di Emanuele Greco). Non sapevo come sfruttare il suggerimento di Emanuele di utilizzare l'elemento RS: ReportViewerHost, ma l'ho risolto utilizzando JavaScript.

Problema

inserisci qui la descrizione dell'immagine

Soluzione

Poiché "overflow: auto" è specificato nell'attributo style dell'elemento div con id "ctl31_ctl10", non possiamo sovrascriverlo in un file di foglio di stile, quindi ho fatto ricorso a JavaScript. Ho aggiunto il seguente codice a "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);
}

Nota

Sembra esserci una soluzione per SSRS 2005 che non ho provato, ma non credo che sia applicabile a SSRS 2008 perché non riesco a trovare la classe "DocMapAndReportFrame".


2
C'è una cosa che non capisco. se applichi la funzione codice FixSari in \ ReportingServices.js, e poi esegui il codice per visualizzare il report in SSRS, dove applichi la funzione per eseguire il codice del metodo sorgente per FixSafari? Se ho capito bene, viene generato il codice originale per ReportingServices.js e alla fine si esegue il codice FixSafari?
What'sUP

12

La mia soluzione basata sulle idee sopra.

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

Non è limitato a un determinato ID e non è necessario includere altre librerie come jQuery.


Ma gli elementi che tutti gli altri prendono di mira, come ctl31_ctl10 e le sue varianti, non contengono necessariamente _fixedTable. Mi sto perdendo qualcosa?
Baodad,

@Baodad: la soluzione precedente utilizza il selettore figlio per trovare il div corretto. Inizia in base a un elemento più in alto nella catena con un attributo id più statico, quindi accompagna i bambini lungo l'albero fino al div desiderato. Preferirei che usasse un nome più descrittivo e meno sovraccarico per la variabile, ma questa è una soluzione altrimenti eccellente. Nome suggerito: reportPayloadElement.
Brian Swift

11

Ecco la soluzione che ho usato per Report Server 2008 R2

Dovrebbe funzionare indipendentemente da ciò che il server di report restituirà per l'utilizzo nell'attributo "id" della tabella. Non credo che si possa sempre presumere che sarà "ctl31_fixedTable"

Ho usato un mix del suggerimento sopra e alcuni modi per caricare dinamicamente le librerie jquery in una pagina dal file javascript trovato qui

Sul server, vai alla directory: C: \ Programmi \ Microsoft SQL Server \ MSRS10_50.MSSQLSERVER \ Reporting Services \ ReportManager \ js

Copia la libreria jquery jquery-1.6.2.min.js nella directory

Crea una copia di backup del file ReportingServices.js Modifica il file. E aggiungi questo in fondo:

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();

Una domanda, tuttavia, se nella pagina è presente più di una tabella di report, ciò non causerà più caricamenti dei controlli? In tal caso, la prima riga potrebbe essere modificata in: var jQueryScriptOutputted = ((typeof (jQueryScriptOutputted) == 'undefined')? False: true);
rmcsharry

4

Puoi risolverlo facilmente con jQuery e un piccolo brutto trucco :-)

Ho una pagina asp.net con un controllo utente ReportViewer.

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

Nell'evento documento pronto avvio quindi un timer e cerco l'elemento che necessita della correzione dell'overflow (come i post precedenti):

 <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>

Meglio che presumere che abbia un certo id. Puoi regolare il timer come preferisci. L'ho impostato a 1000 ms qui.


3

Cordiali saluti, nessuno dei precedenti ha funzionato per me nel 2012 SP1 ... la soluzione semplice era incorporare le credenziali nell'origine dati condivisa e quindi dire a Safari di fidarsi del sito del server SSRS. Poi ha funzionato benissimo! Ci sono voluti giorni per cercare soluzioni presunte come sopra solo per scoprire che la sicurezza integrata non funzionerà in modo affidabile su Safari: devi pasticciare con il portachiavi sul Mac e quindi non funzionerebbe in modo affidabile.


2

La soluzione fornita da Emanuele ha funzionato per me. Potevo vedere il report quando vi ho acceduto direttamente dal server ma quando ho utilizzato un controllo ReportViewer sulla mia pagina aspx, non sono riuscito a vedere il report. Dopo aver ispezionato l'HTML renderizzato, ho trovato un div dall'id "ReportViewerGeneral_ctl09" ( ReportViewerGeneral è l'ID server del controllo del visualizzatore di report) che aveva la sua proprietà di overflow impostata su auto.

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

Ho usato la procedura spiegata da Emanuele per cambiarlo in visibile come segue:

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

    if (element) {
        element.style.overflow = "visible";
    }
}

2

L'ho usato. Aggiungere un riferimento allo script a jquery nella pagina Report.aspx. Usa quanto segue per collegare JQuery agli eventi microsoft. Ho utilizzato un po 'del suggerimento di Eric per impostare l'overflow.

$(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');
                    });
                });
            }
        });
    }
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.