.NET C# 코드로 RDL 보고서를 만드는 방법
페이지 정보
작성자 GrapeCity 작성일 2021-09-28 15:47 조회 1,929회 댓글 0건본문
첨부파일
관련링크
코드로 RDL 보고서를 만들거나, 런타임 환경에서 페이지 또는 RDL 보고서의 데이터 바인딩을 조건부로 관리하거나, 일부 사용자 입력에 따라 보고서 레이아웃을 변경해야 하는 경우가 있을 수 있습니다. 이런 경우 코드로 보고서를 만드는 것을 고려할 수 있습니다.
해당 프로세스를 보여 주기 위해 페이지 왼쪽에 국가 목록을 표시하는 프로젝트를 만들어볼 것입니다. 국가를 선택하면 해당 국가에 거주하는 모든 고객과 해당 고객의 연락처를 보여 주는 보고서가 표시되도록 하려고 합니다(아래 이미지 참조).
이 포스팅에서는 다음 작업을 실행하는 방법을 소개합니다.
코드로 표 컨트롤 만들기
숨겨진 매개 변수를 만들어 보고서로 보내기
JSON 데이터 소스에 바인딩
스타일 컨트롤
동적 보고서에 표현식 사용하기
JSViewer 컴포넌트에서 보고서 보기
프로젝트 설정
먼저, 새 ActiveReports 15 JSViewer Core MVC 응용 프로그램을 만듭니다.
이 보고서 템플릿은 ActiveReports.NET 설치 시 Visual Studio에 통합됩니다. 이 템플릿은 JSViewer에서 보고서를 렌더링하는 데 필요한 NuGet 패키지 및 리소스를 모두 설치하므로 수동으로 설치할 필요가 없습니다.
wwwroot에서 index.html 파일을 엽니다.
Listbox를 사용하여 본문 태그에서 다음과 같이 코드를 수정하고 국가 목록을 표시합니다.
<div style="width: 100%; overflow-x: hidden"> <div style="float:left; width: 125pt" class="main-nav navbar"> <div id='list-heading'>Select Country</div> <ul id="countriesList" class="nav navbar-nav"></ul> </div> <div style="float:right;width:calc(100% - 125pt)" id="viewerContainer"> </div> </div>
그런 다음 본문의 onload 이벤트를 변경하여 countriesList를 채웁니다.
<body onload="populateList()">
아래 코드는 JSON 서비스에서 "countries" 필드를 가져와 정렬된 고유한 목록을 만들고 countriesList 요소를 채우는 방법을 보여 줍니다.
function populateList() { let countriesList = document.getElementById("countriesList"); let oReq = new XMLHttpRequest(); oReq.onload = function () { var lookup = {}; var countriesObj = []; fetch('https://demodata.grapecity.com/northwind/api/v1/Customers') .then(res => res.json()) .then((out) => { for (var item, i = 0; item = out[i++];) { var country = item.country; if (!(country in lookup)) { lookup[country] = 1; countriesObj.push(country); } } countriesObj.sort(); for (let i = 0; i < countriesObj.length; i++) { const countryName = countriesObj[i]; const countries = document.createElement('li'); countries.className = 'countriesList_item'; const countryItem = document.createElement('span'); countryItem.innerText = countryName; countries.appendChild(countryItem); countriesList.appendChild(countries); countries.addEventListener('click', function () { loadViewer(countryName); }); } }) .catch(err => { throw err }); } oReq.open("get", "reports", false); oReq.send(); }
여기서 countriesList 요소를 만들어 채웠고 이벤트 리스너를 추가하여 선택한 국가를 이 목록에서 loadViewer() 함수로 전달했습니다. loadViewer 함수는 사용자 입력, 매개 변수를 가져와 보고서에 전달하여 필터링된 데이터를 표시합니다.
let viewer=null; function loadViewer(country) { if (viewer == null) { viewer = GrapeCity.ActiveReports.JSViewer.create({ element: '#viewerContainer', reportID: "MyReport", reportParameters: [{ name: 'selectedCountry', values: [country] }] }); } else { viewer.openReport("MyReport", [{name: 'selectedCountry', values:[country]}])} }
RDL 보고서 만들기
보고서 폴더에서 RDL 보고서에 대해 사용자 정의 클래스를 만들어 보겠습니다. 이 클래스를 ReportDefinition.cs라고 하겠습니다. RDL 보고서의 public 인스턴스를 만들어 시작해 보겠습니다.
public PageReport rdlReport = new PageReport();
생성자에서 보고서 페이지의 레이아웃을 만듭니다.
rdlReport.Report.PaperOrientation = GrapeCity.ActiveReports.PageReportModel.PaperOrientation.Landscape; rdlReport.Report.PageHeight = "8in"; rdlReport.Report.PageWidth = "11in"; //Page Header GrapeCity.ActiveReports.PageReportModel.PageHeaderFooter headers = new GrapeCity.ActiveReports.PageReportModel.PageHeaderFooter(); rdlReport.Report.PageHeader = headers; headers.Height = ".5in"; headers.PrintOnFirstPage = true; headers.PrintOnLastPage = true; //Page Footer GrapeCity.ActiveReports.PageReportModel.PageHeaderFooter footer = new GrapeCity.ActiveReports.PageReportModel.PageHeaderFooter(); rdlReport.Report.PageFooter = footer; footer.Height = ".5in"; footer.PrintOnFirstPage = true; footer.PrintOnLastPage = true;
다음으로, 페이지 푸터에서 페이지 및 페이지 번호 바로 위에 보고서 제목을 추가합니다.
GrapeCity.ActiveReports.PageReportModel.TextBox reportTitle = new GrapeCity.ActiveReports.PageReportModel.TextBox() { Name = "Report Title", Value = "=\"List of Customers in \" & Parameters!selectedCountry.Value", Height = "0.5in", Width = "5in", Top = "0in", Left = "0.5in", Style = { TextAlign = "Left", FontSize = "18pt", FontWeight = "Bold" } }; GrapeCity.ActiveReports.PageReportModel.TextBox pageNumber = new GrapeCity.ActiveReports.PageReportModel.TextBox(); pageNumber.Name = "pNumber"; pageNumber.Height = ".5cm"; pageNumber.Width = "1cm"; pageNumber.Left = "25cm"; pageNumber.Top = "0cm"; pageNumber.Value = "=Globals!PageNumber"; footer.ReportItems.Add(pageNumber);
보고서에서 필요한 컨트롤을 모두 보고서 정의에 추가합니다. 이 경우에는 "reportTitle" 텍스트 상자를 추가합니다.
rdlReport.Report.Body.ReportItems.Add(reportTitle);
코드로 표 만들기
이 표에는 지정한 국가의 고객 및 해당 고객의 연락처 목록이 표시됩니다. 아래 코드를 사용하여 표 개체의 인스턴스를 만들어 보겠습니다.
GrapeCity.ActiveReports.PageReportModel.Table customersTable = new GrapeCity.ActiveReports.PageReportModel.Table() { Name = "CustomersTable", Top = "0.75in", Left = "0.5in", DataSetName = "MyDataSet" };
이 표에는 열 5개(국가 이름, 연락처 이름, 주소, 도시, 전화번호)와 행 3개(헤더, 세부 정보, 푸터)가 필요합니다. 각 행에 대한 셀을 하나 만들어 5회 사용하여 열을 나타낼 것입니다.
표 헤더의 셀을 나타내는 customerHeader 셀을 만드는 것으로 시작해 보겠습니다.
//Creating table header customersTable.Header = new GrapeCity.ActiveReports.PageReportModel.Header(); customersTable.Header.TableRows.Add(new GrapeCity.ActiveReports.PageReportModel.TableRow() { Height = ".4in" }); var customerHeader = customersTable.Header.TableRows[0].TableCells;
그런 다음 5개의 각 열에 대해 customerHeader 셀의 형식 및 스타일을 지정하고 표에 추가합니다.
//First cell in the table header customerHeader.Add(new GrapeCity.ActiveReports.PageReportModel.TableCell()); customerHeader[0].ReportItems.Add(new GrapeCity.ActiveReports.PageReportModel.TextBox() { Name = "Company Name", Value = "Company Name", Style = { BorderStyle = { Bottom = "Solid" }, VerticalAlign = "Middle", PaddingLeft="3pt", TextAlign = "Left", BackgroundColor = "WhiteSmoke", FontWeight = "Bold" } }); customersTable.TableColumns.Add(new GrapeCity.ActiveReports.PageReportModel.TableColumn() { Width = "2.35in" });
이름, 값, 너비 속성을 적절하게 변경하면서 나머지 4개 열의 형식을 반복해서 지정합니다.
다음으로, 표에 세부 정보 행을 추가합니다. 세부 정보 행은 하나만 필요하고 이 행은 레코드 수만큼 반복됩니다. 세부 정보 행 만들기는 헤더 행 만들기와 절차가 동일합니다. 하지만, 먼저 표 세부 정보 행의 셀을 나타내는 customerDetails 셀을 만듭니다.
//Detail Row customersTable.Details.TableRows.Clear(); customersTable.Details.TableRows.Add(new GrapeCity.ActiveReports.PageReportModel.TableRow() { Height = ".3in" }); var customerDetails = customersTable.Details.TableRows[0].TableCells;
이제, 각 열에 대해 customerDetails 셀의 스타일을 지정하고 세부 정보 행에 추가할 차례입니다.
//First cell in the Details row customerDetails.Add(new GrapeCity.ActiveReports.PageReportModel.TableCell()); customerDetails[0].ReportItems.Add(new GrapeCity.ActiveReports.PageReportModel.TextBox() { Name = "CompanyNameBox", Value = "=Fields!CompanyName.Value", Width = "2.35in", Style = { BorderColor = { Bottom = "WhiteSmoke" }, BorderStyle = { Bottom = "Solid" }, TextAlign = "Left", PaddingLeft="3pt", VerticalAlign="Middle"} });
다시 이름, 값, 너비 속성을 적절하게 변경하면서 나머지 4개 열에 대해 동일한 형식을 반복해서 지정합니다.
마찬가지로, 표 푸터를 만들고 표시된 고객 수를 계산하는 식을 추가합니다.
//Table footer customersTable.Footer = new GrapeCity.ActiveReports.PageReportModel.Footer(); customersTable.Footer.TableRows.Add(new GrapeCity.ActiveReports.PageReportModel.TableRow() { Height = ".5in" }); var customerFooter = customersTable.Footer.TableRows[0].TableCells; //First cell in the footer customerFooter.Add(new GrapeCity.ActiveReports.PageReportModel.TableCell()); customerFooter[0].ReportItems.Add(new GrapeCity.ActiveReports.PageReportModel.TextBox() { Name = "Company Name", Value = "=\"Total Customer Count: \" & CountRows()", Style = { VerticalAlign ="Middle", PaddingLeft="3pt", TextAlign = "Left", FontWeight = "Bold" } }); customersTable.TableColumns.Add(new GrapeCity.ActiveReports.PageReportModel.TableColumn() { Width = "2.35in" });
customersTable이 완성되면 보고서 정의에 추가합니다.
rdlReport.Report.Body.ReportItems.Add(customersTable);
매개 변수 만들기
사용자가 페이지 왼쪽에 있는 목록 상자에서 국가를 선택하면 해당 선택 항목이 보고서 매개 변수를 통해 보고서로 전달됩니다. 다음 섹션에서는 이 매개 변수를 사용하여 데이터 집합을 필터링합니다.
이 매개 변수는 보고서를 렌더링하기 전에 사용자에게 입력하라는 메시지를 표시하거나 메시지를 완전히 숨기는 방식으로 만들 수 있습니다. 매개 변수를 숨기면 사용자에게 매개 변수 값을 입력하라는 메시지가 표시되지 않습니다. 이 경우에는 사용자가 뷰어 컴포넌트 외부에 있는 웹 페이지에서 이미 선택했기 때문에 Hidden 매개 변수로 만들어야 합니다.
//Create a hidden parameter GrapeCity.ActiveReports.PageReportModel.ReportParameter selectedCountry = new GrapeCity.ActiveReports.PageReportModel.ReportParameter() { Name = "selectedCountry", Prompt = "Select a country", Hidden = true }; //Add the parameter to the report rdlReport.Report.ReportParameters.Add(selectedCountry);
데이터 바인딩
데이터 바인딩을 관리하려면 다음과 같이 ReportDefinition 생성자에서 보고서에 데이터 소스와 데이터 집합을 추가합니다.
rdlReport.Report.DataSources.Add(myDataSource()); rdlReport.Report.DataSets.Add(myDataSet());
그런 다음 myDataSource() 메서드를 사용하여 JSON 데이터 소스에 연결합니다.
private GrapeCity.ActiveReports.PageReportModel.DataSource myDataSource() { GrapeCity.ActiveReports.PageReportModel.DataSource myDS = new GrapeCity.ActiveReports.PageReportModel.DataSource(); myDS.Name = "MyDataSource"; myDS.ConnectionProperties.DataProvider = "JSON"; myDS.ConnectionProperties.ConnectString = "jsondoc=https://demodata.grapecity.com/northwind/api/v1/Customers"; return myDS; }
myDataSet() 메서드에서 데이터를 가져옵니다. 또한 데이터 집합에 각 필드를 추가해야 합니다. 아래 코드에서는 앞서 만든 숨겨진 매개 변수를 바탕으로 데이터 집합을 필터링하는 countryFilter를 만듭니다.
private GrapeCity.ActiveReports.PageReportModel.IDataSet myDataSet() { GrapeCity.ActiveReports.PageReportModel.DataSet myDSet = new GrapeCity.ActiveReports.PageReportModel.DataSet(); GrapeCity.ActiveReports.PageReportModel.Query myQuery = new GrapeCity.ActiveReports.PageReportModel.Query(); myDSet.Name = "MyDataSet"; myQuery.DataSourceName = "MyDataSource"; myQuery.CommandText = "$.[*]"; myDSet.Query = myQuery; //Create individual fields GrapeCity.ActiveReports.PageReportModel.Field country = new GrapeCity.ActiveReports.PageReportModel.Field("country", "country", null); GrapeCity.ActiveReports.PageReportModel.Field compName = new GrapeCity.ActiveReports.PageReportModel.Field("companyName", "companyName", null); GrapeCity.ActiveReports.PageReportModel.Field contactName = new GrapeCity.ActiveReports.PageReportModel.Field("contactName", "contactName", null); GrapeCity.ActiveReports.PageReportModel.Field address = new GrapeCity.ActiveReports.PageReportModel.Field("address", "address", null); GrapeCity.ActiveReports.PageReportModel.Field cityName = new GrapeCity.ActiveReports.PageReportModel.Field("city", "city", null); GrapeCity.ActiveReports.PageReportModel.Field phone = new GrapeCity.ActiveReports.PageReportModel.Field("phone", "phone", null); //Create filter to use Parameter GrapeCity.ActiveReports.PageReportModel.Filter countryFilter = new GrapeCity.ActiveReports.PageReportModel.Filter { FilterExpression = "=Fields!country.Value", FilterValues = { "=Parameters!selectedCountry.Value" } }; //Add fields and filter to the dataset myDSet.Fields.Add(country); myDSet.Fields.Add(compName); myDSet.Fields.Add(contactName); myDSet.Fields.Add(address); myDSet.Fields.Add(cityName); myDSet.Fields.Add(phone); myDSet.Filters.Add(countryFilter); return myDSet; }
CustomStore를 사용하여 JSViewer에 보고서 전달
모든 것을 함께 통합하려면 사용자 정의 ReportDefinition 클래스에서 JSViewer로 보고서를 전달하도록 Startup.cs 파일을 수정합니다. 이렇게 하려면 Configure 메서드에서 리포팅 서비스의 UseCustomStore 설정을 활용합니다.
app.UseReporting(settings => { settings.UseEmbeddedTemplates(EmbeddedReportsPrefix, Assembly.GetAssembly(GetType())); settings.UseCustomStore(GetReport); settings.UseCompression = true; });
ReportDefinition 클래스를 호출하고 RDL 보고서를 반환하는 GetReport() 메서드를 만듭니다.
private object GetReport(string arg) { if (!IsReport(arg)) return null; Reports.ReportDefinition reportDef = new Reports.ReportDefinition(); return reportDef.rdlReport; }
마지막으로 이 프로젝트를 실행하면 다음과 같은 결과가 표시됩니다.
자세한 구현 방법 및 코드를 살펴보려면 첨부파일에서 샘플을 다운로드하여 확인해 보시기 바랍니다. 이 프로젝트에는 실행할 필수 ActiveReports.NET 패키지가 필요합니다. ActiveReports.NET이 설치되지 않은 경우 아래 링크에서 최신 버전을 다운로드하십시오.
지금 바로 ActiveReports.NET을 다운로드하여 직접 테스트해보세요!
댓글목록
등록된 댓글이 없습니다.