SSRS 2008 R2 - SSRS 2012 - ReportViewer: รายงานว่างเปล่าใน Safari และ Chrome


84

ฉันย้ายบริการรายงานของเราจากเวอร์ชัน 2008 ไปยังเซิร์ฟเวอร์อื่นเวอร์ชัน 2008 R2 ในเวอร์ชัน 2008 รายงานทำงานได้ดีบน Safari เวอร์ชันใหม่ 2008 R2 รายงานไม่ปรากฏเลย สิ่งที่ฉันเห็นคือส่วนพารามิเตอร์จากนั้นรายงานว่างเปล่า เหมือนกันใน Chrome ตาม Microsoft Safari IS ได้รับการสนับสนุนหากมีข้อ จำกัด รายงานไม่ซับซ้อน ในความเป็นจริงฉันสร้างรายงานที่มีเพียงบรรทัดบนเพื่อดูว่าจะปรากฏใน Safari หรือไม่ แต่ไม่รายงานนั้นก็ว่างเปล่าเช่นกัน ใครทำให้รายงาน SSRS สามารถดูได้บน Safari? ฉันต้องยุ่งกับการตั้งค่าบางอย่างหรือไม่?


คำตอบ:


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"; 
    }
}

หมายเหตุ : ตามที่ azzlak ระบุไว้ชื่อ div ไม่ได้เสมอctl31_ctl10ไป สำหรับ SQL 2012 ลองctl32_ctl09และ 2008 R2 ctl31_ctl09ลอง หากแก้ปัญหานี้ไม่ได้ทำงานดูที่ HTML จากเบราว์เซอร์ของคุณเพื่อดูว่าสคริปต์ได้ทำงานอย่างถูกต้องเปลี่ยนคุณสมบัติการoverflow:autooverflow:visible


โซลูชันสำหรับการควบคุม ReportViewer

แทรกลงใน.aspxหน้า (หรือลงใน.cssไฟล์ที่เชื่อมโยงถ้ามี) เส้นลักษณะนี้

#reportViewer_ctl09 {
  overflow:visible !important;
 }

เหตุผล

Chrome และ Safari แสดงผลoverflow:autoในลักษณะที่แตกต่างกันสำหรับ IE

SSRS HTML คือ QuirksMode HTML และขึ้นอยู่กับบัก 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ในหน้าเว็บที่สร้างขึ้นด้วยตนเองโดยใช้เครื่องมือ Dev ของ Chrome ( F12)


ฉันชอบวิธีแก้ปัญหาของทิมมันง่ายและใช้งานได้จริง

แต่ยังคงมีปัญหาอยู่: เมื่อใดก็ตามที่ผู้ใช้เปลี่ยนพารามิเตอร์ (รายงานของฉันใช้พารามิเตอร์!) AJAX รีเฟรช div, overflow: auto tag จะถูกเขียนใหม่และไม่มีสคริปต์ใดเปลี่ยนแปลง

รายละเอียดเทคโนโลยีนี้อธิบายว่าปัญหาคืออะไร:

สิ่งนี้เกิดขึ้นเนื่องจากในเพจที่สร้างด้วยแผง 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 ได้ด้วยเนื่องจากมีโหมดเริ่มต้นใหม่
Stefan Steiger

8
ทำงานได้อย่างสมบูรณ์ แต่สำหรับ SQL Server 2012, ID ที่กระทำผิด div ctl32_ctl09คือ
azzlack

3
แทนที่จะค้นหา id ctl32_ctl09 หรืออะไรก็ตามที่สร้างขึ้นลอง: document.querySelector ("[id ^ = VisibleReportContent]") parentNode;
พารา

1
@JustinMangum - การใช้ querySelector จะล้มเหลวใน IE ในมุมมองความเข้ากันได้ซึ่งเกือบจะเปิดใช้งานสำหรับไซต์ SSRS อินทราเน็ต อาการคือกล่องโต้ตอบกำลังโหลดจะไม่ปิดดังนั้นผู้ใช้จะไม่สามารถดูรายงานใด ๆ ได้
ไมค์

27

เพียงรวมSizeToReportContent="true"ตามที่แสดงด้านล่าง

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

4
ฉันไม่รู้ว่าทำไมนี่ไม่ใช่วิธีแก้ปัญหาที่ยอมรับเนื่องจาก a) มันใช้งานได้ดีและ b) ดูเหมือนว่าจะเป็นโซลูชันในตัว ไม่ใช่การแฮ็กเพื่อให้โปรแกรมดูรายงานทำงานได้อย่างถูกต้อง ไม่ใช่ว่ามีอะไรผิดปกติกับการแฮ็ก ReportViewer เพื่อให้ใช้งานได้ ดูเหมือนว่าผู้ตรวจสอบรายงานทั้งหมดจะแฮ็คครั้งใหญ่
Raif

3
โซลูชันนี้ใช้กับการฝังตัวควบคุม ReportViewer ในแอปพลิเคชันเท่านั้นไม่ใช่หรือ หากใช้กับเครื่องมือจัดการรายงานและรายงานที่เรียกใช้จาก URL ของ ReportServer โปรดระบุตำแหน่งที่คุณจะต้องรวมการแก้ไขนี้
ผู้ลงทะเบียน

2
คุณกำลังอ้างถึงบรรทัดต่อไปนี้ใน \ SQL \ MSRS11.MSSQLSERVER \ Reporting Services \ ReportServer \ Pages \ ReportViewer.aspx: <RS: ReportViewerHost ID = "ReportViewerControl" runat = "server" />
ผู้ใช้ที่ลงทะเบียน

1
มันอาจจะทำงานได้ดี แต่ถ้าคุณมีจำนวนมากของภาพ (ตัวชี้วัด / Sparklines) ในรายงานก็จะพัดเวลาแสดงผลออกมาอย่างทารุณ
Trubs

1
สิ่งนี้ใช้ไม่ได้เมื่อแก้ไข ReportViewer.aspx ใน SSRS 2012
Keith

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
โซลูชันนี้ทำงานได้ดีในสภาพแวดล้อมของเรา ขอบคุณ Mike
Vince Perta

14

นี่เป็นปัญหาที่ทราบ ปัญหาคือแท็ก div มีลักษณะ "overflow: auto" ซึ่งดูเหมือนว่าจะใช้งานได้ไม่ดีกับ WebKit ซึ่ง Safari และ Chrome ใช้ (ดูคำตอบของ Emanuele Greco) ฉันไม่รู้วิธีใช้ประโยชน์จากคำแนะนำของ Emanuele ในการใช้องค์ประกอบ RS: ReportViewerHost แต่ฉันแก้ไขโดยใช้ JavaScript

ปัญหา

ใส่คำอธิบายภาพที่นี่

วิธีการแก้

เนื่องจากมีการระบุ "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"


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";
    } 
}

ไม่ จำกัด เฉพาะ id บางอย่างและคุณไม่จำเป็นต้องรวมไลบรารีอื่น ๆ เช่น jQuery


แต่องค์ประกอบที่คนอื่นกำหนดเป้าหมายเช่น ctl31_ctl10 และตัวแปรไม่จำเป็นต้องมี _fixedTable อยู่ในองค์ประกอบนั้น ฉันพลาดอะไรไปรึเปล่า?
Baodad

@ Baodad - โซลูชันข้างต้นใช้ Child Selector เพื่อค้นหา div ที่ถูกต้อง โดยเริ่มจากรายการที่อยู่สูงขึ้นไปบนห่วงโซ่โดยมีแอตทริบิวต์ id คงที่มากขึ้นจากนั้นพาเด็ก ๆ ไปตามต้นไม้ไปยัง div ที่ต้องการ ฉันต้องการให้มันใช้ชื่อที่สื่อความหมายมากกว่าสำหรับตัวแปร แต่นี่เป็นวิธีแก้ปัญหาที่ยอดเยี่ยม ชื่อที่แนะนำ: reportPayloadElement
Brian Swift

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>

ดีกว่าสมมติว่ามี id บางอย่าง คุณสามารถปรับเวลาได้ตามต้องการ ฉันตั้งค่าเป็น 1,000 มิลลิวินาทีที่นี่


3

FYI - ไม่มีข้อใดข้างต้นที่ใช้ได้ผลสำหรับฉันใน 2012 SP1 ... วิธีแก้ปัญหาง่ายๆคือการฝังข้อมูลประจำตัวในแหล่งข้อมูลที่แชร์จากนั้นบอก Safari ให้เชื่อถือไซต์เซิร์ฟเวอร์ SSRS แล้วมันก็ใช้งานได้ดี! ใช้เวลาหลายวันในการไล่ตามวิธีแก้ปัญหาที่ควรจะเป็นเช่นเดียวกับข้างต้นเพื่อค้นหาว่าการรักษาความปลอดภัยแบบรวมจะไม่ทำงานได้อย่างน่าเชื่อถือบน Safari - คุณต้องยุ่งกับพวงกุญแจบนเครื่อง Mac จากนั้นก็ยังทำงานไม่ได้


2

วิธีแก้ปัญหาที่ Emanuele ให้ไว้ใช้ได้กับฉัน ฉันสามารถเห็นรายงานเมื่อฉันเข้าถึงโดยตรงจากเซิร์ฟเวอร์ แต่เมื่อฉันใช้การควบคุม 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";
    }
}

2

ฉันเคยใช้สิ่งนี้ เพิ่มการอ้างอิงสคริปต์ไปยัง jquery ในเพจ Report.aspx ใช้สิ่งต่อไปนี้เพื่อเชื่อมโยง JQuery กับเหตุการณ์ของ Microsoft ใช้คำแนะนำเล็กน้อยของ Eric ในการตั้งค่าโอเวอร์โฟลว์

$(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');
                    });
                });
            }
        });
    }
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.