SSRS 2008 R2 - SSRS 2012 - ReportViewer: отчеты пусты в Safari и Chrome

Я перенесла наши службы отчетов с версии 2008 на другую версию сервера 2008 R2. В версии 2008 года отчеты отлично работают на Safari. В новой версии 2008 R2 отчеты не отображаются вообще. Все, что я вижу, это раздел параметров, а затем отчет пуст. То же самое в Chrome. Согласно Microsoft Safari IS поддерживается, если ограниченным образом. Отчеты не сложны. На самом деле я создал отчет, в котором была только строка, чтобы увидеть, будет ли она отображаться в Safari, но нет, этот отчет также полностью пуст. Кто-нибудь делал отчеты SSRS видимыми в Safari? Должен ли я вмешиваться в какой-то настройку конфигурации?

Ответ 1

Окончательное решение (работает и в SSRS 2012!)

Добавьте следующий script в следующий файл (на сервере 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"; 
    }
}

Примечание. Как отмечал azzlak, имя div не всегда ctl31_ctl10. Для SQL 2012 попробуйте ctl32_ctl09 и для 2008 R2 попробуйте ctl31_ctl09. Если это решение не работает, посмотрите на HTML из своего браузера, чтобы убедиться, что script корректно изменил свойство overflow:auto на overflow:visible.


Решение для управления ReportViewer

Вставить в .aspx страницу (или в связанный файл .css, если таковой имеется) эта строка стиля

#reportViewer_ctl09 {
  overflow:visible !important;
 }

Причина

Chrome и Safari отображают overflow:auto по-разному в отношении IE.

SSRS HTML - это QuirksMode HTML и зависит от ошибок IE 5.5. Не-IE браузеры не имеют IE quirksmode и поэтому правильно отображают HTML

Страница HTML, созданная отчетами SSRS 2008 R2, содержит div, который имеет стиль overflow:auto, и превращает отчет в невидимый отчет.

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

Я могу просмотреть отчеты в Chrome, вручную изменив overflow:auto на overflow:visible на созданной веб-странице с помощью инструментов Chrome Dev (F12).


Я люблю решение Тима, это легко и полезно.

Но все еще есть проблема: в любое время пользователь меняет параметры (мои отчеты используют параметры!) AJAX обновляет div, переполнение: автоматический тег перезаписывается, а script его не изменяет.

Эта техническая деталь объясняет, в чем проблема:

Это происходит потому, что на странице, построенной с помощью панелей AJAX, только панели AJAX меняют свое состояние, не обновляя всю страницу. Следовательно, события OnLoad, примененные к тегу <body>, запускаются только один раз: при первой загрузке страницы. После этого изменение любой из панелей AJAX больше не будет вызывать эти события.

Пользователь einarq предложил это решение:

Другой вариант - переименовать свою функцию в pageLoad. Любые функции с этим именем будут вызываться автоматически asp.net ajax, если он существует на странице, также после каждого частичного обновления. Если вы это сделаете, вы также можете удалить атрибут onload из тега body

Так написал улучшенный script, который показан в решении.

Ответ 2

Просто включите SizeToReportContent="true", как показано ниже

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

Ответ 3

Я использую Chrome версии 21 с SQL 2008 R2 SP1, и ни одна из вышеперечисленных исправлений не работала для меня. Ниже приведен код, который работал, как и в других ответах. Я добавил этот бит кода для добавления в "C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\ReportManager\js\ReportingServices.js" (на сервере SSRS):

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

Ответ 4

Это известная проблема. Проблема заключается в том, что тег div имеет стиль "overflow: auto", который, по-видимому, не очень хорошо реализован с помощью WebKit, который используется Safari и Chrome (см. Ответ Emanuele Greco). Я не знал, как использовать предложение Emanuele для использования элемента RS: ReportViewerHost, но я решил его использовать JavaScript.

Проблема

enter image description here

Решение

Так как "overflow: auto" указан в атрибуте style элемента div с id "ctl31_ctl10", мы не можем переопределить его в файле таблиц стилей, поэтому я прибегал к JavaScript. Я добавил следующий код в "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);
}

Примечание

Кажется, существует решение для SSRS 2005, которое я не пробовал, но я не думаю он применим к SSRS 2008, потому что я не могу найти класс DocMapAndReportFrame.

Ответ 5

Вот решение, которое я использовал для Report Server 2008 R2

Он должен работать независимо от того, что будет выводить Сервер отчетов для использования в его атрибуте "id" таблицы. Я не думаю, что вы всегда можете предположить, что это будет "ctl31_fixedTable"

Я использовал сочетание вышеизложенного предложения и некоторые способы динамической загрузки jquery-библиотек на страницу из файла javascript, найденного здесь

На сервере перейдите в каталог: C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Службы Reporting Services\ReportManager\js

Скопируйте jquery-библиотеку jquery-1.6.2.min.js в каталог

Создайте резервную копию файла ReportingServices.js Отредактируйте файл. И добавьте это к нижней части:

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

Ответ 6

Мое решение основано на вышеизложенных идеях.

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

Он не ограничен определенным идентификатором, плюс вам не нужно включать какую-либо другую библиотеку, такую ​​как jQuery.

Ответ 7

Вы можете легко исправить это с помощью jQuery - и немного уродливого взлома: -)

У меня есть страница asp.net с пользовательским элементом ReportViewer.

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

В событии готовности документа я запускаю таймер и ищу элемент, который нуждается в исправлении переполнения (как предыдущие сообщения):

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

Лучше, чем предполагать, что он имеет определенный идентификатор. Вы можете настроить таймер на все, что вам нравится. Я установил его на 1000 мс здесь.

Ответ 8

FYI - ни одно из вышеперечисленных действий для меня в 2012 году SP1... простое решение заключалось в том, чтобы встраивать учетные данные в общий источник данных, а затем сообщать Safari о доверии сайту сервера SSRS. Тогда это сработало! В течение нескольких дней, преследуя предполагаемые решения, подобные выше, только для того, чтобы узнать, что интегрированная безопасность не будет надежно работать на Safari, вам нужно возиться с keychain на маке, а затем все равно не будет работать надежно.

Ответ 9

Решение, предоставленное Эмануэле, сработало для меня. Я мог видеть отчет, когда я обращался к нему напрямую с сервера, но когда я использовал элемент ReportViewer на моей странице aspx, мне не удалось увидеть отчет. После проверки отображаемого HTML я обнаружил div по id "ReportViewerGeneral_ctl09" ( ReportViewerGeneral - это идентификатор сервера средства управления просмотром отчета), который имел свойство переполнения для автоматического.

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

Я использовал процедуру, объясненную Emanuele, чтобы изменить ее на видимую следующим образом:

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

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

Ответ 10

Я использовал это. Добавьте ссылку script на jquery на странице Report.aspx. Используйте следующее, чтобы связать JQuery с событиями Microsoft. Использовал немного предложения Эрика для настройки переполнения.

$(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');
                    });
                });
            }
        });
    }
});