Hide a column on CSV export

4 posts, 0 answers
  1. Rik
    Rik avatar
    2 posts
    Member since:
    Nov 2013

    Posted 19 Sep Link to this post

    Is it possible to conditionally hide (or show) columns when exporting a report to CSV?

    We've noticed that our reports are including subtotals as a column with the value repeated for each row in the same group.  

     

    I figured I could bind the visibility of the textbox to some value that indicates the rendering type (CSV, or other), but I can't find anything that indicates how the report is being rendered.

    I'm using Reports 2017 R2

  2. Todor
    Admin
    Todor avatar
    6 posts

    Posted 21 Sep Link to this post

    Hi Rik,

    In Telerik Reporting when exporting to CSV, Group Header/Footer sections are rendered before/after each detail section. You could hide (some of) this information by modifying programatically the report definition based on the rendering type before processing the report. Then you can programmatically export the modified version of the originally previewed report using Telerik Reporting API.

    Here is sample code how the report definition could be modified, and then the report being exported to CSV file using ReportProcessor RenderReport method.
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.IO;
    using System.Threading;
    using Telerik.Reporting;
    using Telerik.Reporting.Processing;
     
    namespace MyApplication
    {
        public class CsvExporter
        {
            private const string CsvExportFormat = "CSV";
     
            private ReportProcessor reportProcessor;
            private Hashtable deviceInfo;
            private TypeReportSource typeReportSource;
            private string path;
            private ICollection<Stream> streams = new List<Stream>();
     
            public CsvExporter()
            {
                this.path = AppDomain.CurrentDomain.BaseDirectory;
                this.deviceInfo = new Hashtable();
                this.reportProcessor = new ReportProcessor();
                this.typeReportSource = new TypeReportSource();

    // !!! SPECIFY YOUR REPORT TYPE HERE
                this.typeReportSource.TypeName = "ReportLibrary.Report1, ReportLibrary";
            }
             
            public void ToCsv()
            {
                this.Export(CsvExportFormat, this.ModifyReportSource());
            }
             
            private ReportSource ModifyReportSource()
            {
                var typeName = this.typeReportSource.TypeName;
                var reportType = Type.GetType(typeName);
                var reportInstance = (Telerik.Reporting.Report)Activator.CreateInstance(reportType);
                this.SetReportProperty((Telerik.Reporting.ReportItemBase)reportInstance);
     
                ReportSource modifiedReportSource = this.CreateInstanceReportSource(reportInstance, this.typeReportSource);
     
                return modifiedReportSource;
            }
     
            private ReportSource CreateInstanceReportSource(IReportDocument report, ReportSource originalReportSource)
            {
                var instanceReportSource = new InstanceReportSource { ReportDocument = report };
                instanceReportSource.Parameters.AddRange(originalReportSource.Parameters);
                return instanceReportSource;
            }
     
            private void SetReportProperty(Telerik.Reporting.ReportItemBase reportItemBase)
            {
                if (reportItemBase.Items.Count < 1)
                    return;
     
                if (reportItemBase is Telerik.Reporting.Report)
                {
    // !!! CHANGE YOUR REPORT DEFINITION HERE
    // In the current scenario the 4th column of the productTable would be hidden
                    var report = (Telerik.Reporting.Report)reportItemBase;
                    Telerik.Reporting.Table reportItem = (Telerik.Reporting.Table)report.Items["detailSection"].Items["productTable"];
     
                    reportItem.ColumnGroups[3].Visible = false;
                }
            }
     
            private void Export(string exportFormat, ReportSource reportSource)
            {
                Thread thread = new Thread(() =>
                {
                    RenderingResult renderResult = this.reportProcessor.RenderReport(exportFormat, reportSource, this.deviceInfo);
                    string fileName = $"{renderResult.DocumentName}.{renderResult.Extension}";
                    string filePath = Path.Combine(this.path, fileName);
     
                    using (FileStream fs = new FileStream(filePath, FileMode.Create))
                    {
                        fs.Write(renderResult.DocumentBytes, 0, renderResult.DocumentBytes.Length);
                    }
                });
     
                thread.SetApartmentState(ApartmentState.STA);
                thread.Start();
            }
        }
    }
    Note that the class CsvExporter should be instantiated and its public method ToCsv() called/attached where appropriate (for example to button click event).

    Note also that you can exclude static text from the CSV output by setting NoStaticText to True in the CSV device information. The device information could be provided programmatically, or in <Telerik.Reporting> configuration section.


    Regards,
    Todor
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. Rik
    Rik avatar
    2 posts
    Member since:
    Nov 2013

    Posted 22 Sep in reply to Todor Link to this post

    Thanks for the reply Todor.

    I'd have to adapt this approach to be more generic to my situation as we have a number of reports where we may want to hide data from group footers.

    Do you know if this can be hooked into the built-in export feature on the report viewer? (I'm working in a web environment by the way)

    Rik

  4. Todor
    Admin
    Todor avatar
    6 posts

    Posted 25 Sep Link to this post

    Hello Rik,

    I don't think that the provided approach can be hooked to the reportviewer, since in each report the report definition and the data you would like to hide would be generally different.

    On the other hand, the most of the code in the CsvExporter class could be reused as it doesn't depend on the exact report definition. An abstract class could be created for this purpose.
    Note that the type of the report (this.typeReportSource.TypeName) could be provided via constructor parameter.
    The SetReportProperty method hides/changes particular report item(s) and could be an abstract method to be implemented by each ancestor of the abstract CsvExporter.
    Based on particular report definitions it might be possible to generalize further.

    Let us know if you need more assistance.

    Regards,
    Todor
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top