首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >LocalReport导出到Excel的速度真的很慢

LocalReport导出到Excel的速度真的很慢
EN

Stack Overflow用户
提问于 2014-05-21 15:38:16
回答 3查看 8.9K关注 0票数 3

我们有一个Asp.Net页面,它针对后端的Oracle运行report,这在导出到Excel电子表格时非常慢。我已经做了一些调查,并确定查询本身不应该受到责备--我可以使用seconds直接针对Oracle运行查询,并在大约5秒内将结果导出到Excel,但是当我通过asp.net页面和ReportViewer控件运行查询时,返回时间大约需要3分钟。

有谁有什么建议来解释为什么这么慢?这个查询返回大约8000行,每个行大约有30列,所以它不是一个很小的结果集,但它也不是很大。任何关于我们如何优化报告的建议都将不胜感激。

我正在使用Microsoft.ReportViewer.WebForms版本10.0.0.0,有人知道v11是否有性能改进吗?

编辑:尝试了ReportViewer v11,没有提高速度。

EN

回答 3

Stack Overflow用户

发布于 2015-09-14 05:17:55

如果您的报告中有分组。从.NET 4开始,当遗留CAS被移除时,本地处理的RDLC报告需要花费大量时间来执行动态分组或动态过滤器。有一个关于这个https://social.msdn.microsoft.com/Forums/sqlserver/en-US/6d89e2ce-3528-465f-9740-7e22aa7b7aae/slow-performance-with-dynamic-grouping-and-reportviewer-in-local-mode?forum=sqlreportingservices的现有讨论

我找到的最好的解决办法是,

  1. 创建一个新的.NET 3.5库项目,并创建一个实际处理报表的文件。

代码语言:javascript
运行
复制
using Microsoft.Reporting.WebForms;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;

//As you would expect, the new assembly WebReportviewer.FullTrustReportviewer
//all it does is just run the report. that's it. here is the code, it should be in a separated project:

namespace WebReportviewer
{
    [Serializable]
    public class FullTrustReportviewer : MarshalByRefObject
    {
        private ReportViewer FullTrust;
        public FullTrustReportviewer()
        {
            FullTrust = new ReportViewer();
            FullTrust.ShowExportControls = false;
            FullTrust.ShowPrintButton = true;
            FullTrust.ShowZoomControl = true;
            FullTrust.SizeToReportContent = false;
            FullTrust.ShowReportBody = true;
            FullTrust.ShowDocumentMapButton = false;
            FullTrust.ShowFindControls = true;
            //FullTrust.LocalReport.SubreportProcessing += LocalReport_SubreportProcessing;
            //FullTrust.LocalReport.SetBasePermissionsForSandboxAppDomain(new PermissionSet(PermissionState.Unrestricted));
        }

        public void Initialize(string DisplayName, string ReportPath, bool Visible, ReportParameter[] reportParam, string reportRenderFormat, string deviceInfo, string repMainContent, List<string[]> repSubContent)
        {
            FullTrust.LocalReport.DisplayName = DisplayName;
            FullTrust.LocalReport.ReportPath = ReportPath;
            //FullTrust.Visible = Visible;
            //FullTrust.LocalReport.LoadReportDefinition(new StringReader(repMainContent));
            FullTrust.LocalReport.SetParameters(reportParam);

            repSubContent.ForEach(x =>
            {
                FullTrust.LocalReport.LoadSubreportDefinition(x[0], new StringReader(x[1]));
            });
            FullTrust.LocalReport.DataSources.Clear();
        }

        public byte[] Render(string reportRenderFormat, string deviceInfo)
        {
            return FullTrust.LocalReport.Render(reportRenderFormat, deviceInfo);
        }
        public void AddDataSources(string p, DataTable datatable)
        {
            FullTrust.LocalReport.DataSources.Add(new ReportDataSource(p, datatable));
        }

        public SubreportProcessingEventHandler SubreportProcessing { get; set; }

        public static void LocalReport_SubreportProcessing(object sender, SubreportProcessingEventArgs e)
        {
            LocalReport lr = (LocalReport)sender;

            e.DataSources.Clear();
            ReportDataSource rds;

            if (e.ReportPath.Contains("DataTable2"))
            {
                DataTable dt = (DataTable)lr.DataSources["DataTable2"].Value;
                DataView dv = new DataView(dt);
                dv.RowFilter = string.Format("Id={0}", e.Parameters["Id"].Values[0]);
                rds = new ReportDataSource("DataTable2", dv.ToTable());
                e.DataSources.Add(rds);
            }
        }
    }
}
  1. 从现有项目调用代码

代码语言:javascript
运行
复制
 public static byte[] GeneratePBAReport()
        {


            string l_spName = string.Empty;
            string l_reportPath = string.Empty;
            var repCol = new List<ReportDataSource>();

            var repParCol = new ReportParameter[1];
            if (id == "")
            {

                l_reportPath = HttpContext.Current.Server.MapPath("~\\.rdlc");
                l_spName = "";
            }
            else
            {
                l_reportPath = HttpContext.Current.Server.MapPath("~\\.rdlc");
                l_spName = "";
            }

            repParCol[0] = new ReportParameter("pID", "");

            var ds = new DataSet();
            using (var sqlCmd = new SqlCommand(l_spName, new SqlConnection(ConfigurationManager.ConnectionStrings[""].ConnectionString)))
            {
                sqlCmd.CommandType = CommandType.StoredProcedure;
                var sqlParam = new SqlParameter() { Value = "", ParameterName = "" };
                sqlCmd.Parameters.Add(sqlParam);
                sqlCmd.CommandTimeout = 300;
                using (var sqlAdapter = new SqlDataAdapter(sqlCmd))
                {
                    sqlAdapter.Fill(ds);
                }
            }

            var rds = new ReportDataSource();
            rds.Name = "";
            rds.Value = ds.Tables[0];
            //l_report.DataSources.Add(rds);
            repCol.Add(rds);

            rds = new ReportDataSource();
            rds.Name = "";
            rds.Value = ds.Tables[1];
            //l_report.DataSources.Add(rds);
            repCol.Add(rds);

            rds = new ReportDataSource();
            rds.Name = "";
            rds.Value = ds.Tables[2];
            //l_report.DataSources.Add(rds);
            repCol.Add(rds);

            rds = new ReportDataSource();
            rds.Name = "";
            rds.Value = ds.Tables[3];
            //l_report.DataSources.Add(rds);
            repCol.Add(rds);

            Warning[] warnings;
            string[] streamids;
            string mimeType;
            string encoding;
            string extension;
            string deviceInfo;


            deviceInfo = "<DeviceInfo><SimplePageHeaders>True</SimplePageHeaders></DeviceInfo>";

            return NewDomainReport.Render("PDF", deviceInfo, "-" , l_reportPath, true, repCol, string.Empty, new List<string[]>(), repParCol);
        }

为了进行真正快速的测试,您可以尝试像本文中提到的那样在web.config中添加CAS。

在ASP.NET应用程序中,可以在<trust legacyCasModel="true" level="Full"/>文件的system.web部分使用web.config实现相同的结果。

如果速度显着提高,上述代码的行为将相同。以上代码的好处是创建一个单独的AppDomain,而不是影响整个解决方案。

票数 3
EN

Stack Overflow用户

发布于 2019-05-06 14:24:11

添加<trust legacyCasModel="true" level="Full"/>对我来说不是一个选项,因为我在代码中使用dynamic类型。

此代码正在工作:

代码语言:javascript
运行
复制
public class CustomReportRenderer
{
    public static byte[] RenderReport(string reportPath, string rdlcDSName, DataTable rdlcDt, ReportParameter[] rptParams, string downloadFormat, out string mimeType, out string filenameExtension)
    {
        var assemblyDir = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath);
        AppDomainSetup setup = new AppDomainSetup()
        {
            ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
            ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile,
            LoaderOptimization = LoaderOptimization.MultiDomainHost,
            PrivateBinPath = assemblyDir
        };

        setup.SetCompatibilitySwitches(new[] { "NetFx40_LegacySecurityPolicy" });
        AppDomain _casPolicyEnabledDomain = AppDomain.CreateDomain("Full Trust", null, setup);
        try
        {
            FullTrustReportviewer rpt = (FullTrustReportviewer)_casPolicyEnabledDomain.CreateInstanceFromAndUnwrap(typeof(FullTrustReportviewer).Assembly.CodeBase, typeof(FullTrustReportviewer).FullName);
            rpt.Initialize(reportPath, rptParams);
            var bytes = rpt.Render(rdlcDSName, rdlcDt, downloadFormat, out mimeType, out filenameExtension);
            return bytes;
        }
        finally
        {
            AppDomain.Unload(_casPolicyEnabledDomain);
        }
    }

}

[Serializable]
public class FullTrustReportviewer : MarshalByRefObject
{
    private ReportViewer FullTrust;
    public FullTrustReportviewer()
    {
        FullTrust = new ReportViewer();
        FullTrust.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Local;
    }

    public void Initialize(string reportPath, ReportParameter[] rptParams)
    {
        FullTrust.LocalReport.ReportPath = reportPath;
        FullTrust.LocalReport.SetParameters(rptParams);

    }
    public byte[] Render(string rdlcDSName, DataTable rdlcDt, string downloadFormat, out string mimeType, out string filenameExtension)
    {
        Warning[] warnings;
        string[] streamids;
        string encoding;
        FullTrust.LocalReport.DataSources.Add(new ReportDataSource(rdlcDSName, rdlcDt));
        var bytes = FullTrust.LocalReport.Render(downloadFormat, null, out mimeType, out encoding, out filenameExtension, out streamids, out warnings);
        return bytes;

    }
}

从aspx或mvc控制器方法调用RenderReport方法

代码语言:javascript
运行
复制
var bytes = CustomReportRenderer.RenderReport(rdlcFileFullPath, "ReportsDataSet", ds.Tables[0], rptParams, downloadFormat, out mimeType, out extension);
// Now that you have all the bytes representing the PDF report, buffer it and send it to the client.
Response.Buffer = true;
Response.Clear();
Response.ContentType = mimeType;
Response.AddHeader("content-disposition", "attachment; filename=" + fileName + "." + extension);
Response.BinaryWrite(bytes); // create the file
Response.Flush(); // send it to the client to download
票数 1
EN

Stack Overflow用户

发布于 2019-01-24 23:13:00

可能要归咎于简单的表达式和条件格式。

我们的一份报告在大数据(2万多行)方面有一个非常类似的问题。查询正在快速返回数据,但是生成到屏幕的速度很慢,导出到excel的速度更慢。使用报表查看器10和12的问题是相同的。

令我惊讶的是,删除tablix排序日期格式表达式交替背景行颜色表达式使该报告生成速度快得多,导出excel的时间从超过半小时延长到大约一分钟。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23787853

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档