SSRS 2008 R2 - SSRS 2012 - ReportViewer: os relatórios estão em branco no Safari e Chrome

84

Migrei nossos serviços de relatório da versão 2008 para outra versão de servidor 2008 R2. Na versão 2008, os relatórios funcionam bem no Safari. Na nova versão 2008 R2 os relatórios não aparecem de todo. Tudo o que vejo é a seção de parâmetros e, em seguida, o relatório está em branco. O mesmo no Chrome. De acordo com o Microsoft, o Safari é suportado de forma limitada. Os relatórios não são complexos. Na verdade, criei um relatório que só tinha uma linha para ver se ele apareceria no Safari, mas não, esse relatório também está completamente em branco. Alguém tornou os relatórios SSRS visíveis no Safari? Eu tenho que mexer com algum tipo de definição de configuração?

Anita C
fonte
duplicado: stackoverflow.com/questions/5428017/…
Tim Partridge

Respostas:

109

Solução final (funciona no SSRS 2012 também!)

Anexe o seguinte script ao seguinte arquivo (no 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"; 
    }
}

Observação : como azzlak observou, o nome do div nem sempre ctl31_ctl10. Para SQL 2012, tente ctl32_ctl09e para 2008 R2, tente ctl31_ctl09. Se esta solução não funcionar, examine o HTML do seu navegador para ver se o script funcionou corretamente alterando a overflow:autopropriedade para overflow:visible.


Solução para controle ReportViewer

Insira na .aspxpágina (ou em um .cssarquivo vinculado , se disponível) esta linha de estilo

#reportViewer_ctl09 {
  overflow:visible !important;
 }

Razão

O Chrome e o Safari são renderizados de overflow:automaneiras diferentes em relação ao IE.

SSRS HTML é QuirksMode HTML e depende de bugs do IE 5.5. Navegadores não-IE não têm o modo quirks do IE e, portanto, renderizam o HTML corretamente

A página HTML produzida pelos relatórios do SSRS 2008 R2 contém um divque possui overflow:autoestilo e transforma o relatório em um relatório invisível.

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

Posso ver relatórios no Chrome mudando manualmente overflow:autopara overflow:visiblena página da web produzida usando as Ferramentas de Desenvolvimento do Chrome ( F12).


Adoro a solução do Tim , é fácil e funciona.

Mas ainda há um problema: sempre que o usuário altera os parâmetros (meus relatórios usam parâmetros!), O AJAX atualiza o div, a tag overflow: auto é reescrita e nenhum script a altera.

Este detalhe de nota técnica explica qual é o problema:

Isso ocorre porque em uma página construída com painéis AJAX, apenas os painéis AJAX mudam de estado, sem atualizar a página inteira. Consequentemente, os OnLoadeventos que você aplicou na <body>tag são disparados apenas uma vez: a primeira vez que sua página é carregada. Depois disso, a alteração de qualquer um dos painéis AJAX não acionará mais esses eventos.

O usuário einarq sugeriu esta solução :

Outra opção é renomear sua função para pageLoad. Quaisquer funções com este nome serão chamadas automaticamente pelo asp.net ajax se existir na página, também após cada atualização parcial. Se você fizer isso, você também pode remover o atributo onload da tag body

Então escreveu o script aprimorado que é mostrado na solução.

Emanuele Greco
fonte
1
Alterei a função page_load para pageLoad a fim de acionar o script. Caso contrário, parece resolver os problemas de renderização no Chrome 13. Infelizmente, a autenticação básica no SSRS parece não funcionar com o Safari 5.1, então não posso verificar lá.
kermatt
A razão é ERRADA. O verdadeiro motivo é que SSRS HTML é QuirksMode HTML e depende de bugs do IE 5.5. Navegadores não-IE não têm o modo quirksmode do IE e, portanto, exibem o HTML corretamente. Para navegadores que não emulam os bugs do IE 5.5 em seu QuirksMode, falta definir a largura da tabela ... Isso também se aplica ao IE 10, já que tem um novo modo quirksmode padrão.
Stefan Steiger
8
Funciona perfeitamente. Mas para o SQL Server 2012, o ID div ofensivo é ctl32_ctl09.
azzlack
3
em vez de pesquisar o id ctl32_ctl09 ou o que quer que seja gerado, tente: document.querySelector ("[id ^ = VisibleReportContent]"). parentNode;
Para
1
@JustinMangum - o uso de querySelector falhará no IE em Compatibility View, que quase certamente está habilitado para sites SSRS de intranet. O sintoma é que a caixa de diálogo Carregando nunca fecha, então os usuários não poderão visualizar nenhum relatório.
Mike
27

Apenas inclua SizeToReportContent="true"conforme mostrado abaixo

<rsweb:ReportViewer ID="ReportViewer1" runat="server" SizeToReportContent="True"...
Deepak
fonte
4
Não sei por que essa não é a solução aceita, pois a) funciona bem eb) parece ser a solução embutida. Não é um hack para fazer o reportviewer funcionar corretamente. Não que haja algo de errado em hackear o ReportViewer para fazê-lo funcionar. Parece que todo o reportviewer está em uma grande invasão.
Raif
3
Esta solução não se aplica apenas à incorporação do controle ReportViewer em um aplicativo? Se isso se aplica ao Report Manager e relatórios executados a partir do URL ReportServer, especifique onde você precisa incluir esta edição.
Usuário registrado em
2
Você está se referindo à seguinte linha em \ SQL \ MSRS11.MSSQLSERVER \ Reporting Services \ ReportServer \ Pages \ ReportViewer.aspx: <RS: ReportViewerHost ID = "ReportViewerControl" runat = "server" />
Usuário registrado de
1
Ele pode funcionar bem, mas se você tem um monte de imagens (indicadores / Sparklines) em um relatório que vai explodir o tempo de renderização fora atrozmente.
Trubs
1
Isso não funciona ao modificar ReportViewer.aspx no SSRS 2012.
Keith
23

Estou usando o Chrome versão 21 com SQL 2008 R2 SP1 e nenhuma das correções acima funcionou para mim. Abaixo está o código que funcionou, assim como com as outras respostas adicionei este trecho de código ao Anexo a "C: \ Arquivos de programas \ Microsoft SQL Server \ MSRS10_50.MSSQLSERVER \ Reporting Services \ ReportManager \ js \ ReportingServices.js" (em o Servidor 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
fonte
1
Esta solução está funcionando muito bem em nosso ambiente. Obrigado Mike
Vince Perta
14

Este é um problema conhecido . O problema é que uma tag div tem o estilo "overflow: auto" que aparentemente não é implementado bem com o WebKit que é usado pelo Safari e Chrome (veja a resposta de Emanuele Greco). Não sabia como aproveitar a sugestão de Emanuele de usar o elemento RS: ReportViewerHost, mas resolvi usando JavaScript.

Problema

insira a descrição da imagem aqui

Solução

Como "overflow: auto" é especificado no atributo style do elemento div com id "ctl31_ctl10", não podemos substituí-lo em um arquivo de folha de estilo, então recorri ao JavaScript. Anexei o seguinte código a "C: \ Arquivos de programas \ 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 haver uma solução para o SSRS 2005 que eu não tentei, mas não acho que seja aplicável ao SSRS 2008 porque não consigo encontrar a classe "DocMapAndReportFrame".

Tim Partridge
fonte
2
Há uma coisa que não entendo. se você aplicar a função de código FixSari em \ ReportingServices.js e, em seguida, executar o código para exibir o relatório em SSRS, onde aplicará a função para executar o código do método-fonte para FixSafari? Se bem entendi, o código original para ReportingServices.js é gerado e no final você executa o código FixSafari?
What'sUP
12

Minha solução com base nas ideias acima.

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

Não está limitado a um determinado id e você não precisa incluir nenhuma outra biblioteca, como jQuery.

Jim Bauwens
fonte
Mas os elementos que todos os outros estão almejando, como ctl31_ctl10 e suas variantes, não têm necessariamente _fixedTable neles. Estou esquecendo de algo?
Baodad
@Baodad - A solução acima usa o seletor filho para encontrar o div correto. Ele começa com base em um item mais acima na cadeia com um atributo id mais estático, em seguida, desce os filhos na árvore até o div desejado. Eu preferiria que ele usasse um nome mais descritivo e menos sobrecarregado para a variável, mas esta é uma solução excelente. Nome sugerido: reportPayloadElement.
Brian Swift
11

Aqui está a solução que usei para o Report Server 2008 R2

Deve funcionar independentemente do que o Report Server produzirá para uso em seu atributo "id" da tabela. Eu não acho que você sempre pode assumir que será "ctl31_fixedTable"

Eu usei uma combinação da sugestão acima e algumas maneiras de carregar dinamicamente as bibliotecas jquery em uma página a partir do arquivo javascript encontrado aqui

No servidor, vá para o diretório: C: \ Arquivos de programas \ Microsoft SQL Server \ MSRS10_50.MSSQLSERVER \ Reporting Services \ ReportManager \ js

Copie a biblioteca jquery jquery-1.6.2.min.js para o diretório

Crie uma cópia de backup do arquivo ReportingServices.js Edite o arquivo. E anexe isso na parte inferior:

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
fonte
Uma pergunta, porém, se houver mais de uma tabela de relatório na página, isso não causará várias cargas de controles? Nesse caso, a primeira linha pode ser alterada para: var jQueryScriptOutputted = ((typeof (jQueryScriptOutputted) == 'undefined')? False: true);
rmcsharry
4

Você pode corrigir isso facilmente com jQuery - e um pequeno hack feio :-)

Eu tenho uma página asp.net com um controle de usuário ReportViewer.

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

No evento de documento pronto, inicio um cronômetro e procuro o elemento que precisa da correção de estouro (como postagens 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>

Melhor do que assumir que tem um certo id. Você pode ajustar o cronômetro para o que quiser. Eu o defino em 1000 ms aqui.

Henebb
fonte
3

Para sua informação - nenhuma das opções acima funcionou para mim em 2012 SP1 ... uma solução simples era incorporar credenciais na fonte de dados compartilhada e então dizer ao Safari para confiar no site do servidor SSRS. Então funcionou muito bem! Demorou dias perseguindo supostas soluções como acima apenas para descobrir que a segurança integrada não funcionaria de forma confiável no Safari - você tem que mexer com as chaves no mac e então ainda não funcionaria de forma confiável.

Gary Melhaff
fonte
2

A solução fornecida pela Emanuele funcionou para mim. Pude ver o relatório quando o acessei diretamente do servidor, mas quando usei um controle ReportViewer na minha página aspx, não consegui ver o relatório. Ao inspecionar o HTML renderizado, encontrei um div pelo id "ReportViewerGeneral_ctl09" ( ReportViewerGeneral é o id do servidor do controle do visualizador de relatório) que tinha sua propriedade de estouro definida como auto.

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

Usei o procedimento explicado por Emanuele para mudar isso para visível da seguinte forma:

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

    if (element) {
        element.style.overflow = "visible";
    }
}
Samir K
fonte
2

Eu usei isso. Adicione uma referência de script a jquery na página Report.aspx. Use o seguinte para vincular JQuery aos eventos da Microsoft. Usei um pouco da sugestão de Eric para definir o estouro.

$(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
fonte