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

84

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

Анита С
источник
дубликат: stackoverflow.com/questions/5428017/…
Тим Партридж,

Ответы:

109

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

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

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


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

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

#reportViewer_ctl09 {
  overflow:visible !important;
 }

Причина

Chrome и Safari визуализируют overflow:autoиначе, чем IE.

SSRS HTML - это HTML QuirksMode, который зависит от ошибок IE 5.5. Браузеры, отличные от IE, не имеют quirksmode IE и, следовательно, правильно отображают 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 Tools ( F12).


Мне нравится решение Тима , оно простое и работает.

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

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

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

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

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

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

Эмануэле Греко
источник
1
Я изменил функцию page_load на pageLoad, чтобы запускать скрипт. В противном случае, похоже, это решает проблемы с рендерингом в Chrome 13. К сожалению, базовая аутентификация в SSRS не работает с Safari 5.1, поэтому я не могу проверить там.
kermatt
Причина НЕПРАВИЛЬНАЯ. Настоящая причина в том, что SSRS HTML является QuirksMode HTML и зависит от ошибок IE 5.5. Браузеры, отличные от IE, не имеют режима quirksmode IE и, следовательно, правильно отображают HTML. Для браузеров, которые не эмулируют ошибки IE 5.5 в своем QuirksMode, отсутствует установка ширины таблицы ... Кстати, это также относится к IE 10, так как в нем есть новый режим quirksmode по умолчанию.
Stefan Steiger
8
Прекрасно работает. Но для SQL Server 2012 оскорбительный идентификатор div ctl32_ctl09.
azzlack
3
вместо поиска id ctl32_ctl09 или любого другого сгенерированного кода попробуйте: document.querySelector ("[id ^ = VisibleReportContent]"). parentNode;
Para
1
@JustinMangum - использование querySelector не удастся в IE в режиме совместимости, который почти наверняка включен для сайтов SSRS интрасети. Симптомом является то, что диалоговое окно «Загрузка» никогда не закроется, поэтому пользователи не смогут просматривать какие-либо отчеты.
Майк
27

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

<rsweb:ReportViewer ID="ReportViewer1" runat="server" SizeToReportContent="True"...
Дипак
источник
4
Я не знаю, почему это не приемлемое решение, так как а) оно работает нормально и б) кажется встроенным решением. Это не хитрость для правильной работы Reportviewer. Не то чтобы во взломе ReportViewer, чтобы заставить его работать, что-то не так. Похоже, что весь Reportviewer взломан.
Raif
3
Разве это решение не применимо только для встраивания элемента управления ReportViewer в приложение? Если это относится к диспетчеру отчетов и отчеты запускаются с URL-адреса ReportServer, укажите, где вам нужно будет включить это изменение.
Зарегистрированный пользователь
2
Вы имеете в виду следующую строку в \ SQL \ MSRS11.MSSQLSERVER \ Reporting Services \ ReportServer \ Pages \ ReportViewer.aspx: <RS: ReportViewerHost ID = "ReportViewerControl" runat = "server" />
Зарегистрированный пользователь
1
Это может работать нормально, но если у вас много изображений (индикаторов / спарклайнов) в отчете, время рендеринга ужасно истощится.
Trubs
1
Это не работает при изменении ReportViewer.aspx в SSRS 2012.
Кейт,
23

Я использую 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";         
    } 
}
Майкл Браун
источник
1
Это решение очень хорошо работает в нашей среде. Спасибо, Майк
Винс Перта
14

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

Проблема

введите описание изображения здесь

Решение

Поскольку "overflow: auto" указано в атрибуте style элемента div с идентификатором 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».

Тим Партридж
источник
2
Я одного не понимаю. если вы примените функцию кода FixSari в \ ReportingServices.js, а затем выполните код для отображения отчета в SSRS, где вы примените функцию для выполнения кода исходного метода для FixSafari? Если я правильно понимаю, создается исходный код ReportingServices.js и в конце концов вы выполняете код FixSafari?
What'sUP
12

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

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

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

Джим Баувенс
источник
Но элементы, на которые нацелены все остальные, такие как ctl31_ctl10 и его варианты, не обязательно содержат _fixedTable. Я что-то упускаю?
Baodad
@Baodad - в приведенном выше решении используется дочерний селектор для поиска правильного div. Он начинается с элемента выше по цепочке с более статическим атрибутом id, а затем ведет детей вниз по дереву к желаемому div. Я бы предпочел использовать для переменной более информативное, менее перегруженное имя, но в остальном это отличное решение. Предлагаемое имя: reportPayloadElement.
Брайан Свифт,
11

Вот решение, которое я использовал для 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();
Эрик Вайс
источник
Однако есть вопрос: если на странице есть более одной таблицы отчета, не вызовет ли это многократной загрузки элементов управления? Если это так, то самую первую строку можно изменить на: var jQueryScriptOutputted = ((typeof (jQueryScriptOutputted) == 'undefined')? False: true);
rmcsharry
4

Вы можете легко исправить это с помощью 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 мс.

Henebb
источник
3

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

Гэри Мелхафф
источник
2

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

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

Я использовал процедуру, описанную Эмануэлем, чтобы изменить это на видимое, как показано ниже:

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

    if (element) {
        element.style.overflow = "visible";
    }
}
Самир К
источник
2

Я использовал это. Добавьте ссылку на скрипт на 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');
                    });
                });
            }
        });
    }
});
MeyC
источник