-포함된 보고서 만들기

아래와같이 부모리포트안에 자식리포트가 들어가는 경우가 되게 많다.

이때 자식리포트바인딩 방법과 부모 데이터를 자식리포트로 값을 넘기는 방법을 아래에서 설명 중.. ㅋ

image

 

자식리포트 삽입 작업화면

image

 

일단 위의 화면은 보고서가 두개이다

부모가 되는 리포트는 아래와 바인딩했다.

리포트 바인딩하기

 //리포트생성
ReportViewer reportViewer = new ReportViewer();
reportViewer.ProcessingMode = ProcessingMode.Local;
reportViewer.LocalReport.ReportEmbeddedResource = "WpfApplication1.Report1.rdlc";
reportViewer.LocalReport.EnableExternalImages = true;

 

자식리포트는 부모리포트에서 자식 리포트를 클릭한 다음 경로를 잡아 주면된다.

image

완성된  화면

아래 Sub report 부터는 wpfApplication1.ReportSub.rdlc 파일이다.

image

데이터바인딩

부모리포트가 바인딩 될 때 자식 리포트에 값을 바인딩 해주어야 한다.

그러기 위해선 SubreportProcessing 이벤트를 걸어서 바인딩시점에서 값을 넣어주면된다.

                //리포트생성
                ReportViewer reportViewer = new ReportViewer();
                reportViewer.ProcessingMode = ProcessingMode.Local;
                reportViewer.LocalReport.ReportEmbeddedResource = "WpfApplication1.Report1.rdlc";
                reportViewer.LocalReport.EnableExternalImages = true;

                ReportDataSource ds = new ReportDataSource("DataSet1", this._personlist);
                reportViewer.LocalReport.DataSources.Add(ds);
                //서브리포트의 데이터 바인딩을 위해 걸어둔다.
                reportViewer.LocalReport.SubreportProcessing += new SubreportProcessingEventHandler(LocalReport_SubreportProcessing);
                
                
                this.windowsFormsHost1.Child = reportViewer; //WPF
                reportViewer.RefreshReport();

 

 

자식리포트에 값 바인딩하기

e.Parameters["PersonKey"].Values[0]; 로 부모리포트의 값을 알아낼수있다.

 

        void LocalReport_SubreportProcessing(object sender, SubreportProcessingEventArgs e)
        {
            //서브디렉토리 데이터 바인딩..          

            string PersonKey =e.Parameters["PersonKey"].Values[0]; //부모데이터의 값 받아오기            

            var query = from c in this._personaddr
                        where c.PersonKey == PersonKey
                        select c;

            e.DataSources.Add(new ReportDataSource("DataSet1", query));
        }

 

 

-부모리포트에서 자식리포트로 부모의 파라메터 값 넘겨주기

부모리포트에서 자식리포트로 값을 넘겨줄 수 있다.

아래는 파라메터로 값을 넘기는 방법이다.

 

부모리포트에서 자식리포트에다가 파라메터를 지정해준다.

image

여기서는 PersonKey를 예제로 넘기고 있다.

image

 

자식리포트 파라메터변수 설정

다시 자식리포트에서 파라메터를 설정해준다.

중요! 부모리포트에서 넘기는 매개변수 이름과 자식매개변수이름이 같아야한다.

image

 

리포트에서 출력된 값

image

 

전체소스

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Reporting.WinForms;

namespace WpfApplication1
{
    /// <summary>
    /// ReportTest.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class ReportTest : Window
    {
        List<Person> _personlist;
        List<PersonAddr> _personaddr;
        public ReportTest()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(ReportTest_Loaded);  
        }

        void ReportTest_Loaded(object sender, RoutedEventArgs e)
        {
            //구라 데이터만들기
            _personlist = new List<Person>();
            _personaddr = new List<PersonAddr>();

            for (int i = 0; i < 30; i++)
            {
               string personkey = Guid.NewGuid().ToString();
                //사용자정보데이터
               _personlist.Add(new Person() { PersonKey = personkey, Age = i, Name = "jaedoo"+i.ToString() , Sex = 1 });
                //주소데이터
               _personaddr.Add(new PersonAddr() { PersonKey = personkey, addr1 = "부산광역시", addr2 = string.Format("동래구 온천동 {0}동", i.ToString()) });
            }


            CreateReport();


        }

        public void CreateReport()
        {
            try
            {
                //리포트생성
                ReportViewer reportViewer = new ReportViewer();
                reportViewer.ProcessingMode = ProcessingMode.Local;
                reportViewer.LocalReport.ReportEmbeddedResource = "WpfApplication1.Report1.rdlc";
                reportViewer.LocalReport.EnableExternalImages = true;

                ReportDataSource ds = new ReportDataSource("DataSet1", this._personlist);
                reportViewer.LocalReport.DataSources.Add(ds);
                //서브리포트의 데이터 바인딩을 위해 걸어둔다.
                reportViewer.LocalReport.SubreportProcessing += new SubreportProcessingEventHandler(LocalReport_SubreportProcessing);
                
                
                this.windowsFormsHost1.Child = reportViewer; //WPF
                reportViewer.RefreshReport();

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        void LocalReport_SubreportProcessing(object sender, SubreportProcessingEventArgs e)
        {
            //서브디렉토리 데이터 바인딩..          

            string PersonKey =e.Parameters["PersonKey"].Values[0]; //부모데이터의 값 받아오기            

            var query = from c in this._personaddr
                        where c.PersonKey == PersonKey
                        select c;

            e.DataSources.Add(new ReportDataSource("DataSet1", query));
        }

    }


}

 

데이터용으로 사용된 가라 데이터

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WpfApplication1
{
    public class Person
    {
        public Person()
        {

        }

        public Person(string name, int age, int sex)
        {
            this.Name = name;
            this.Age = age;
            this.Sex = sex;
        }

        public string PersonKey { get; set; }

        public string Name { set; get; }

        public int Age { set; get; }

        public int Sex { set; get; }

        
    }
    /// <summary>
    /// 서브디렉토리 데이터
    /// </summary>
    public class PersonAddr
    {
       public string addr1 { set; get; }
       public string addr2 { set; get; }

       public string PersonKey { get; set; }
    }


}

 

비주얼스튜디오에 기본내장되어져 있는Microsoft 보고서

라이센스도 무료고 나름 강력한 리포트!

 

 
 

UI 만들기

WPF 에서는 리포트 뷰 따위가 없기때문에 WindowsFormsHost 이용해서 WinFrom 의 컨트롤을 이용한다.
<WindowsFormsHost Name="windowsFormsHost1" Margin="0,46,0,0" />         
간지난다!
 
        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            ReportViewer reportViewer = new ReportViewer();

            reportViewer.ProcessingMode = ProcessingMode.Local;
            reportViewer.LocalReport.ReportEmbeddedResource = "테스트용.Report2.rdlc";
            
            this.windowsFormsHost1.Child = reportViewer;
            reportViewer.RefreshReport();
        }
 

바인딩에 사용될 개체

    public class Person
    {
        public int Age { set; get; }
        public string Name { set; get; }
    }

리포트 만들기

Person 개체를 리포트에서 뿌려줄꺼이므로 데이터소스에서 Person을 선택

개체선택
 
바인딩할려는 대상개체를 선택합니다. 아래와 같이 만들어진다.
 
보고서 데이터 이거 볼려면 보기 > 보고서 데이터 클릭
매개변수에 바로 접근도 가능
reportViewer.LocalReport.SetParameters(new ReportParameter("Title", "이미지 로드 테스트"));
 

Person 리스트 만들기

테이블을 끌어서 리포트에 적용.
 
 
대략 발로 만들어진 리포트
 
이상하게 머릿글 입력하는 부분에 직접 Name을 적으면 N a m e 이렇게 글자가 퍼진다 ㅡ_ㅡ
문자를 붙여넣기하면 바로 나옴> 
 

데이터 바인딩하기

위에서 데이터 집합 이름을 DataSet1 으로 선언했따 여기에 List<Person> 담아주면 끗
        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            ReportViewer reportViewer = new ReportViewer();

            reportViewer.ProcessingMode = ProcessingMode.Local;
            reportViewer.LocalReport.ReportEmbeddedResource = "테스트용.Report2.rdlc";
            
            //데이터 바인딩
            List<Person> personList = new List<Person>();
            personList.Add(new Person() { Age = 10, Name = "kojaedoo1" });
            personList.Add(new Person() { Age = 20, Name = "kojaedoo2" });
            personList.Add(new Person() { Age = 30, Name = "kojaedoo3" });
            personList.Add(new Person() { Age = 40, Name = "kojaedoo4" });

            ReportDataSource personListSource = new ReportDataSource("DataSet1", personList);
            reportViewer.LocalReport.DataSources.Add(personListSource);
            
            this.windowsFormsHost1.Child = reportViewer;
            reportViewer.RefreshReport();
        }
 
 
 

리포트뷰어에서 이미지 출력하기

보고서 데이터에 매개변수를 추가한다. ReportLogo 이게 왼쪽에 
이미지가 바인딩된다.
이미지에서 속성보기를 클릭
이미지 원본선택에서 데이터베이스로 선택
필드에서 : =System.Convert.FromBase64String(Parameters!ReportLogo.Value) //ReportLogo는 아까 만든 매개변수이름
MIME 형식사용에서 : image/png

 

웹클라이언트로 이미지를 받아와서 ToBase64String로 변경한다.

 

WebClient wc = new WebClient();
Stream imageStream = wc.OpenRead("https://t1.daumcdn.net/cfile/tistory/177612134B839BE557");
string baseLogo = ConvertImageToBase64(System.Drawing.Image.FromStream(imageStream), System.Drawing.Imaging.ImageFormat.Bmp);

reportViewer.LocalReport.SetParameters(new ReportParameter("ReportLogo", baseLogo));


//ConvertImageToBase64소스
        private string ConvertImageToBase64(System.Drawing.Image image, System.Drawing.Imaging.ImageFormat format)
        {
            byte[] byteImage;
            using (System.IO.MemoryStream imageStream = new System.IO.MemoryStream())
            {
                image.Save(imageStream, format);
                byteImage = new byte[imageStream.Length];
                imageStream.Seek(0, System.IO.SeekOrigin.Begin);

                imageStream.Read(byteImage, 0, (int)imageStream.Length);
            }

            return System.Convert.ToBase64String(byteImage);

        }

 

전체소스

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.Reporting.WinForms;
using System.Net;
using System.IO;

namespace 테스트용
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {


   
        public MainWindow()
        {
            this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            ReportViewer reportViewer = new ReportViewer();

            reportViewer.ProcessingMode = ProcessingMode.Local;
            reportViewer.LocalReport.ReportEmbeddedResource = "테스트용.Report2.rdlc";
            
            //데이터 바인딩
            List<Person> personList = new List<Person>();
            personList.Add(new Person() { Age = 10, Name = "kojaedoo1" });
            personList.Add(new Person() { Age = 20, Name = "kojaedoo2" });
            personList.Add(new Person() { Age = 30, Name = "kojaedoo3" });
            personList.Add(new Person() { Age = 40, Name = "kojaedoo4" });

            ReportDataSource PersonnelEducation = new ReportDataSource("DataSet1", personList);
            reportViewer.LocalReport.DataSources.Add(PersonnelEducation);


            reportViewer.LocalReport.SetParameters(new ReportParameter("Title", "이미지 로드 테스트"));


            WebClient wc = new WebClient();
            Stream imageStream = wc.OpenRead("https://t1.daumcdn.net/cfile/tistory/177612134B839BE557");
            string baseLogo = ConvertImageToBase64(System.Drawing.Image.FromStream(imageStream), System.Drawing.Imaging.ImageFormat.Bmp);

            reportViewer.LocalReport.SetParameters(new ReportParameter("ReportLogo", baseLogo));

            this.windowsFormsHost1.Child = reportViewer;
            reportViewer.RefreshReport();
        }


        private string ConvertImageToBase64(System.Drawing.Image image, System.Drawing.Imaging.ImageFormat format)
        {
            byte[] byteImage;
            using (System.IO.MemoryStream imageStream = new System.IO.MemoryStream())
            {
                image.Save(imageStream, format);
                byteImage = new byte[imageStream.Length];
                imageStream.Seek(0, System.IO.SeekOrigin.Begin);

                imageStream.Read(byteImage, 0, (int)imageStream.Length);
            }

            return System.Convert.ToBase64String(byteImage);

        }

    }



}

더많은 정보

http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=KO-KR&k=k(VS100.RTP.RPTDESIGNER.LAYOUTVIEW.F1);k(TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV4.0%22)&rd=true

+ Recent posts