SSRS 2008 R2 - SSRS 2012 - ReportViewer: los informes están en blanco en Safari y Chrome


84

Migré nuestros servicios de informes de la versión 2008 a otra versión de servidor 2008 R2. En la versión 2008, los informes funcionan bien en Safari. La nueva versión 2008 R2 los informes no aparecen en absoluto. Todo lo que veo es la sección de parámetros y luego el informe está en blanco. Lo mismo en Chrome. De acuerdo con Microsoft Safari, se admite aunque de forma limitada. Los informes no son complejos. De hecho, creé un informe que solo tenía una línea para ver si aparecería en Safari, pero no, ese informe también está completamente en blanco. ¿Alguien hizo que los informes de SSRS fueran visibles en Safari? ¿Tengo que meterme con algún tipo de ajuste de configuración?


Respuestas:


109

Solución definitiva (¡también funciona en SSRS 2012!)

Agregue la siguiente secuencia de comandos al siguiente archivo (en el servidor 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 : Como señaló azzlak, el nombre del div no siempre es ctl31_ctl10. Para SQL 2012 intente ctl32_ctl09y para 2008 R2 intente ctl31_ctl09. Si esta solución no funciona, mire el HTML de su navegador para ver si el script ha funcionado correctamente cambiando la overflow:autopropiedad a overflow:visible.


Solución para el control ReportViewer

Inserte en la .aspxpágina (o en un .cssarchivo vinculado , si está disponible) esta línea de estilo

#reportViewer_ctl09 {
  overflow:visible !important;
 }

Razón

Chrome y Safari se renderizan overflow:autode manera diferente con respecto a IE.

SSRS HTML es QuirksMode HTML y depende de los errores de IE 5.5. Los navegadores que no son de IE no tienen el modo peculiar de IE y, por lo tanto, procesan el HTML correctamente

La página HTML producida por los informes de SSRS 2008 R2 contiene un divque tiene overflow:autoestilo y convierte el informe en un informe invisible.

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

Puedo ver informes en Chrome cambiando manualmente overflow:autoa overflow:visibleen la página web producida usando las herramientas de desarrollo de Chrome ( F12).


Me encanta la solución de Tim , es fácil y funciona.

Pero todavía hay un problema: cada vez que el usuario cambia los parámetros (¡mis informes usan parámetros!) AJAX actualiza el div, la etiqueta overflow: auto se reescribe y ningún script lo cambia.

Este detalle de la nota técnica explica cuál es el problema:

Esto sucede porque en una página construida con paneles AJAX, solo los paneles AJAX cambian su estado, sin actualizar toda la página. En consecuencia, los OnLoadeventos que aplicó en la <body>etiqueta solo se activan una vez: la primera vez que se carga su página. Después de eso, cambiar cualquiera de los paneles AJAX ya no activará estos eventos.

El usuario einarq sugirió esta solución :

Otra opción es cambiar el nombre de su función a pageLoad. Cualquier función con este nombre será llamada automáticamente por asp.net ajax si existe en la página, también después de cada actualización parcial. Si hace esto, también puede eliminar el atributo onload de la etiqueta del cuerpo

Entonces escribió el script mejorado que se muestra en la solución.


1
Modifiqué la función page_load a pageLoad para activar el script. De lo contrario, parece resolver problemas de renderizado en Chrome 13. Desafortunadamente, la autenticación básica en SSRS no parece funcionar con Safari 5.1, por lo que no puedo verificar allí.
kermatt

La razón es INCORRECTA. La verdadera razón es que SSRS HTML es QuirksMode HTML y depende de los errores de IE 5.5. Los navegadores que no son IE no tienen el modo peculiar de IE y, por lo tanto, procesan el HTML correctamente. Para los navegadores que no emulan los errores de IE 5.5 en su QuirksMode, carece de establecer el ancho de la tabla ... Esto también se aplica a IE 10 por cierto, ya que tiene un nuevo modo de quirksmode predeterminado.
Stefan Steiger

8
Funciona perfectamente. Pero para SQL Server 2012, el div id infractor es ctl32_ctl09.
azzlack

3
en lugar de buscar la identificación ctl32_ctl09 o lo que se genere, intente: document.querySelector ("[id ^ = VisibleReportContent]"). parentNode;
Para

1
@JustinMangum: el uso de querySelector fallará en IE en la Vista de compatibilidad, que es casi seguro que está habilitado para los sitios SSRS de la intranet. El síntoma es que el cuadro de diálogo Cargando nunca se cerrará, por lo que los usuarios no podrán ver ningún informe.
Mike

27

Solo incluye SizeToReportContent="true"como se muestra a continuación

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

4
No sé por qué esta no es la solución aceptada ya que a) funciona bien yb) parece ser la solución incorporada. No es un truco para que el visor de informes funcione correctamente. No es que haya nada malo en piratear ReportViewer para que funcione. Parece que todo el visor de informes está en un gran truco.
Raif

3
¿No se aplica esta solución solo para incrustar el control ReportViewer en una aplicación? Si esto se aplica al Administrador de informes y los informes se ejecutan desde la URL de ReportServer, especifique dónde debe incluir esta edición.
Usuario registrado

2
¿Se refiere a la siguiente línea en \ SQL \ MSRS11.MSSQLSERVER \ Reporting Services \ ReportServer \ Pages \ ReportViewer.aspx: <RS: ReportViewerHost ID = "ReportViewerControl" runat = "server" />
Usuario registrado

1
Se puede trabajar bien, pero si usted tiene un montón de imágenes (indicadores / minigráficos) en un informe que volará el tiempo de presentación cabo atroz.
Trubs

1
Esto no funciona al modificar ReportViewer.aspx en SSRS 2012.
Keith

23

Estoy usando Chrome versión 21 con SQL 2008 R2 SP1 y ninguna de las correcciones anteriores funcionó para mí. A continuación se muestra el código que funcionó, como con las otras respuestas, agregué este código para agregar a "C: \ Archivos de programa \ Microsoft SQL Server \ MSRS10_50.MSSQLSERVER \ Reporting Services \ ReportManager \ js \ ReportingServices.js" (en el servidor SSRS):

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

1
Esta solución está funcionando muy bien en nuestro entorno. Gracias Mike
Vince Perta

14

Este es un problema conocido . El problema es que una etiqueta div tiene el estilo "overflow: auto" que aparentemente no está bien implementado con WebKit, que es utilizado por Safari y Chrome (ver la respuesta de Emanuele Greco). No supe cómo aprovechar la sugerencia de Emanuele de usar el elemento RS: ReportViewerHost, pero lo resolví usando JavaScript.

Problema

ingrese la descripción de la imagen aquí

Solución

Dado que "overflow: auto" se especifica en el atributo de estilo del elemento div con id "ctl31_ctl10", no podemos anularlo en un archivo de hoja de estilo, así que recurrí a JavaScript. Agregué el siguiente código a "C: \ Archivos de programa \ 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

Parece haber una solución para SSRS 2005 que no he probado, pero no creo que sea aplicable a SSRS 2008 porque no puedo encontrar la clase "DocMapAndReportFrame".


2
Hay una cosa que no entiendo. si aplica la función de código FixSari en \ ReportingServices.js, y luego ejecuta el código para mostrar el informe en SSRS, ¿dónde aplica la función para ejecutar el código del método fuente para FixSafari? Si lo entiendo correctamente, se genera el código original de ReportingServices.js y al final se ejecuta el código FixSafari?
What'sUP

12

Mi solución basada en las ideas anteriores.

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

No se limita a una determinada identificación y no es necesario que incluya ninguna otra biblioteca como jQuery.


Pero los elementos a los que se dirigen todos los demás, como ctl31_ctl10 y sus variantes, no necesariamente tienen _fixedTable en ellos. ¿Me estoy perdiendo de algo?
Baodad

@Baodad: la solución anterior usa el Selector de niños para encontrar el div correcto. Comienza en base a un elemento más arriba en la cadena con un atributo de identificación más estático, luego lleva a los niños por el árbol hasta el div deseado. Preferiría que se usara un nombre más descriptivo y menos sobrecargado para la variable, pero esta es una solución excelente. Nombre sugerido: reportPayloadElement.
Brian Swift

11

Aquí está la solución que utilicé para Report Server 2008 R2

Debería funcionar independientemente de lo que generará el servidor de informes para su uso en su atributo "id" de la tabla. No creo que siempre puedas asumir que será "ctl31_fixedTable"

Usé una combinación de la sugerencia anterior y algunas formas de cargar dinámicamente bibliotecas jquery en una página desde el archivo javascript que se encuentra aquí

En el servidor, vaya al directorio: C: \ Archivos de programa \ Microsoft SQL Server \ MSRS10_50.MSSQLSERVER \ Reporting Services \ ReportManager \ js

Copie la biblioteca jquery jquery-1.6.2.min.js en el directorio

Cree una copia de seguridad del archivo ReportingServices.js Edite el archivo. Y agregue esto al final de la misma:

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

Sin embargo, una pregunta, si hay más de una tabla de informes en la página, ¿no causará esto múltiples cargas de los controles? Si es así, la primera línea podría cambiarse a: var jQueryScriptOutputted = ((typeof (jQueryScriptOutputted) == 'undefined')? False: true);
rmcsharry

4

Puede solucionar esto fácilmente con jQuery, y un pequeño truco feo :-)

Tengo una página asp.net con un control de usuario ReportViewer.

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

En el evento de documento listo, luego inicio un temporizador y busco el elemento que necesita la corrección de desbordamiento (como publicaciones anteriores):

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

Mejor que asumir que tiene cierta identificación. Puede ajustar el temporizador a lo que quiera. Lo configuré en 1000 ms aquí.


3

Para su información, nada de lo anterior funcionó para mí en 2012 SP1 ... una solución simple fue incrustar credenciales en la fuente de datos compartida y luego decirle a Safari que confíe en el sitio del servidor SSRS. ¡Entonces funcionó muy bien! Tomó días persiguiendo supuestas soluciones como las anteriores solo para descubrir que la seguridad integrada no funcionará de manera confiable en Safari: tiene que meterse con el llavero en la Mac y luego aún no funcionaría de manera confiable.


2

La solución proporcionada por Emanuele funcionó para mí. Pude ver el informe cuando accedí a él directamente desde el servidor, pero cuando usé un control ReportViewer en mi página aspx, no pude ver el informe. Al inspeccionar el HTML renderizado, encontré un div con la identificación "ReportViewerGeneral_ctl09" ( ReportViewerGeneral es la identificación del servidor del control del visor de informes) que tenía su propiedad de desbordamiento establecida en auto.

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

Usé el procedimiento explicado por Emanuele para cambiar esto a visible de la siguiente manera:

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

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

2

He usado esto. Agregue una referencia de script a jquery en la página Report.aspx. Utilice lo siguiente para vincular JQuery a los eventos de microsoft. Usé un poco de la sugerencia de Eric para configurar el desbordamiento.

$(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');
                    });
                });
            }
        });
    }
});
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.