LazarusCompleteGuide:12.6

From 흡혈양파의 번역工房
Jump to: navigation, search

라자루스를 이용해 보고서 만들기

어떤 데이터베이스 애플리케이션도 조작하고 있는 데이터를 인쇄하는 기능이 없다면 완전하다고 할 수 없다. 전통적으로 이러한 보고 유형은 특수화된 보고 엔진이 처리한다. FastReport가 이러한 기능으로 널리 사용되는 보고 엔진(reporting engine)으로, 이 엔진을 이용하는 사람은 비단 오브젝트 파스칼 개발자뿐만이 아니다. FastReport의 오래된 배포판은 (2.32) 오브젝트 파스칼 개발자들에게 무료로 배포되도록 만들어졌다. 해당 버전은 이후 라자루스 팀에 의해 개발되었고, 라자루스로 번들된 보고서 툴인 LazReport의 기반을 형성한다.


설치

LazReport 패키지는 라자루스와 함께 배포되지만 기본적으로 IDE에 설치되어 있진 않다. 따로 설치를 요하며, 'Installed package' 대화창에서 이루어진다. LazReport 를 설치할 때는 'Printer4Lazarus' 패키지 또한 컴파일 및 설치된다. 설치가 끝나면 컴포넌트 팔레트에 'LazReport'라는 새 탭과 함께 표 12.25의 컴포넌트들이 생긴다.

컴포넌트 설명
TFrReport 실제 보고하는 컴포넌트.
TFrDBDataset 이 객체는 TfrReport 컴포넌트와 보고서에 사용하고자 하는 TDataset 자손 사이에 연결을 형성한다.
TFrBarCodeObject 이 객체를 폼에 드롭하면 리포트 디자이너에게 바코드 객체에 대한 지원을 추가할 수 있다. 이후 이 객체는 보고서(report)에 바코드를 그리도록 해준다.
TFrRoundRectObject 이 객체를 폼에 드롭하면 리포트 디자이너에게 둥근 직사각형에 대한 지원을 추가할 수 있다. 이후 이 객체는 보고서에 둥근 직사각형을 그리도록 해준다.
TFrShapeObject 이 객체를 폼에 드롭하면 리포트 디자이너에게 모든 종류의 도형에 대한 (직사각형, 원형, 삼각형 등) 지원을 추가할 수 있다.
TfrCheckboxObject 이 객체를 폼에 드롭하면 리포트 디자이너에게 체크상자를 그리기 위한 지원을 추가할 수 있다.
TfrCompositeReport 이 객체는 다중 보고서를 하나의 인쇄 작업으로 합치도록 해준다.
TfrUserDataset 이 객체는 임시 데이터를 기반으로 보고서를 생성하도록 해준다. 일부 이벤트의 도움으로 'TDataset' 를 가상 구현(emulate) 수 있다.
TfrTextExport 생성된 보고서를 텍스트로 내보낸다.
TfrHTMLExport 생성된 보고서를 HTML로 내보낸다.
TfrCSVExport 생성된 보고서를 CSV(콤마로 구분된 값) 파일로 내보낸다.
TfrPrintGrid TDBGrid 컴포넌트의 내용을 인쇄한다.
표 12.25: 컴포넌트 팔레트에 표시되는 컴포넌트


그림 12.21: lazreport에 의해 설치되는 컴포넌트


LazReport는 밴드 보고서(banded report) 생성기이다. 즉, 다수의 밴드로 구성되고, 각 밴드에는 인쇄 가능한 요소(텍스트, 이미지, 도형)가 다수 포함되어 있음을 의미한다. 밴드에 위치한 요소라면 보고서 엔진이 그 밴드를 인쇄해야겠다고 결정할 때마다 인쇄할 수 있다. 요소들은 설계된 위치에 인쇄되지만 인쇄될 때 밴드의 시작 위치를 기준으로 한다.


밴드에는 여러 유형이 있다:

  • 보고서 헤더(header)와 보고서 푸터(footer) 밴드는 한 번만 인쇄되며, 헤더는 보고서의 시작에, 푸터는 끝에 인쇄된다. 보고서 시작 제목과 끝맺는 데이터 요약에 사용하기 좋다.
  • 페이지 헤더와 페이지 푸터 밴드. 보고서 페이지마다 상단과 하단에 인쇄된다. 페이지 번호, 누계, 인쇄 일자와 시간, 또는 회사 로고를 표시할 때 사용할 수 있다.
  • 열 헤더와 푸터 밴드. 페이지 헤더와 푸터 밴드와 많이 닮았지만 보고서의 열마다 그 상단과 하단에 인쇄된다. 주상(columnar) 리스트에서 (예: 연락처 데이터가 있는 고객 리스트) 열 제목은 주상(columnar) 데이터의 기술을 ('고객 이름', '고객 폰 번호', '고객 이메일' 등) 포함할 것이다.
  • 데이터 밴드. 데이터 세트에서 레코드마다 한 번씩 인쇄될 것이다. 데이터세트는 실제 TDataset, 혹은 데이터세트의 이벤트 기반 시뮬레이션이 (TfrUserDataset 컴포넌트 이용) 될 수도 있다.
  • 그룹 헤더와 그룹 푸터 밴드. 데이터세트 내 각 레코드마다 계산된 표현식을 바탕으로 레코드를 그룹화하는 것이 가능하다. (주어진 기간 동안 송장 리스트에 있는 고객 번호가 될 수 있다.)
    해당 표현식이 변경되자마자 보고 엔진은 새 그룹을 시작하고, 그룹 헤더 밴드를 인쇄한다.
    그룹이 끝나면 그룹 푸터 밴드가 인쇄된다. 이로 인해 그룹 총계를 제공할 수 있게 된다 (예: 각 고객의 송장에 대한 합계).
    다중 그룹핑 수준을 정의할 수도 있다. (송장은 고객마다 분기별로 그룹화 가능)
  • 자식(Child) 밴드: 때로는 하나의 밴드를 이용해 데이터를 정확하게 배치하기가 불가능하다. 이런 경우, 자식 밴드를 첫 번째 밴드에 부착함으로써 본인이 명시하는 변수에 따라 밴드들 중 선택할 수 있다.


각 보고서 밴드에는 하나 또는 그 이상의 인쇄 가능한 요소들을 드롭할 수 있으며, 이 때 이용 가능한 요소들도 여러 개가 있다:

  • 임의 크기로 된 텍스트 요소. 텍스트는 정적 텍스트와 표현식이 섞일 수 있다. 보고 엔진이 텍스트 요소를 표시하기 전에 이는 템플릿 텍스트를 검사하고 그 곳에서 발견되는 표현식을 모두 계산한다. 정적 텍스트와 계산된 텍스트의 결합 결과가 되는 텍스트가 인쇄된다.
  • 도형. 직선을 그리도록 해준다.
  • 이미지. 인쇄된 이미지는 정적이거나, blob 필드에서 검색할 수 있다.
  • 바코드. 표현식으로부터 계산할 수 있는 바코드를 인쇄할 수 있다.
  • 체크상자. 일부 부울 표현식(boolean expression)의 평가에 따라 체크 마크를 표시하기 위해 체크상자를 사용할 수 있다.


마지막으로, 생성된 보고서는 사용자가 직접 또는 생성된 보고서를 미리보기 하면서 파일로 내보낼 수 있다. 현재 평문, HTML 또는 CSV(이것을 사용 시 데이터의 포맷팅은 거의 손실되지만 텍스트로 된 데이터는 파일로 내보내짐)으로 내보낼 수 있다.


보고서 생성하기

보고서는 데이터모듈이나 폼에 드롭할 수 있다. 보고서 생성은 아래 두 가지 단계로 구성된다:

  1. 보고서가 TDataset 자손으로부터 데이터를 표시해야 하는 경우, 데이터세트를 생성해야 한다. 선택적으로 TDatasource 를 이용할 수도 있지만 필수조건은 아니다.
  2. 보고서에 사용되는 데이터세트마다 폼 또는 데이터모듈에 TfrDBDataset 컴포넌트를 드롭해야 한다. 그것의 Dataset 또는 DataSource 프로퍼티를 단계 1에서 생성된 데이터세트로 설정해야 한다.
  3. TFrReport 컴포넌트를 폼에 드롭해야 한다. 그것의 Dataset 프로퍼티는 앞 단계에서 생성된 TFrDBDataset 컴포넌트 중 하나로 설정되어야 한다.
  4. 마지막으로 TFrReport 의 컨텍스트 메뉴를 이용해 보고서 설계를 시작한다.


리포트 디자이너(Report Designer) 창에는 GUI 디자이너에서 예상할 법한 요소들이 있다: 객체를 추가하는 버튼들; 객체를 정렬하는 버튼들; 프로퍼티 인스펙터. 디자이너의 요소들 중 일부는 다수의 텍스트 에디터에서 찾을 수 있는 폰트 및 텍스트 정렬 버튼들을 연상시킨다.


새 보고서의 설계는 주로 보고서에 Master Data 밴드를 추가하여 시작된다: 이를 위해 툴바에서 페이지뷰 좌측까지 있는 [Band] 버튼을 (상단에서 두 번째 버튼) 사용해야 한다. 페이지에서 위치해야 하는 곳을 클릭하고 나면 밴드 유형을 선택하고, 여기서 Master Data를 선택해야 한다. 선택이 완료되면 master 데이터 밴드로 연결되어야 하는 데이터세트를 선택해야 한다. 밴드는 표시해야 하는 데이터를 가진 데이터세트로 연결되어야 한다. 페이지에 추가로 밴드를 드롭할 수 있는데, 가령 단순히 제목을 표시하는 보고서 헤더 밴드, 페이지 번호와 일자를 표시하는 페이지 푸터 밴드, 아니면 표시된 데이터에 대한 열 헤더를 표시하는 열 헤더 밴드를 드롭할 수 있겠다.


보고서에서 열의 수는 오브젝트 인스펙터에서 설정 가능한데, 보고서의 각 페이지에는 사용할 열의 수를 나타내는 Columns 프로퍼티가 있기 때문이다.


리포트 디자이너의 모습은 그림 12.22와 같다.

그림 12.22: 리포트 디자이너 창


텍스트의 표시는, [Add text] 버튼을 이용하여 텍스트를 표시해야 하는 밴드 위를 클릭한다. 인쇄할 텍스트를 편집하는 에디터가 나타난다. 이것은 몇 가지 특수 기능을 포함한 간단한 텍스트 에디터로, 일반 텍스트와 혼합된 변수, 데이터베이스 필드, 함수를 삽입하는 기능이 포함되어 있다. 사실상 보고 엔진은 꺾쇠괄호 [ ] 안의 내용이라면 무조건 평가해야 하는 함수로 취급하며, 평가 결과는 괄호 위치에 있는 텍스트에 삽입될 것이다. [DB Fields] 버튼을 클릭하면 필드 리스트가 나타나고, 그 중 하나를 선택할 수 있다. 에디터는 큰 따옴표 사이에 필드명과 함께 데이터세트의 이름을 삽입할 것이다.


[Function] 버튼을 클릭하면 함수의 기능을 향상시키는데, 이름을 모두 대문자로 인쇄하는 기능을 예로 들 수 있겠다. 텍스트 에디터에서 [Variable] 버튼을 클릭하면 다양한 특수 보고서 변수들을 삽입할 수 있다. 이러한 변수들은 일자, 시간, 현재 페이지 번호 등을 포함할 수 있다. 가령 이러한 요소들을 푸터 밴드에 위치시킬 수도 있다.


[Format] 버튼은 수치형 또는 일자/시간 결과를 가진 변수나 공식(formulae)의 포맷팅을 명시하거나, 수치형 필드에 소수 자리 수를 지정하는 등의 기능에 사용된다. 보고서가 완료되면 인쇄하거나 미리보기를 할 수 있다:

procedure TForm1.BPreviewClick(Sender: TObject);
begin
  if FRPupils.PrepareReport then FRPupils.ShowPreparedReport
  else
    ShowMessage('Prepare report failed !');
end;


PrepareReport 호출은 메모리에 보고서를 준비할 것이다. 만일 이 작업이 성공하면 보고서는 ShowPreparedReport 호출을 이용해 화면의 미리보기 창에서 미리 볼 수 있다. 아니면 PrintPreparedReport 프로시저를 이용해 보고서를 프린터로 즉시 전송하는 방법도 있다:

procedure TForm1.BPrintClick(Sender: TObject);
  var R : TFrReport;
begin
  R:=SelectedReport;
  if R.PrepareReport then
    R.PrintPreparedReport(",1)
  else
    ShowMessage('Prepare report failed !');
end;


PrintPreparedReport 에 대한 첫 번째 인수는 인쇄해야 하는 페이지 집합을 명시하는 문자열이다: 빈 채로 놔두면 모든 페이지가 인쇄될 것이다. 보통 '1, 5-8' 범위로 표시하여 1페이지, 그리고 5페이지부터 8페이지까지 인쇄하도록 포함시킬 수 있다. 두 번째 인수는 인쇄 매수(copies)가 된다. 보고서를 미리보기 하는 동안 사용자는 인쇄 전에 프린터를 선택하거나 파일로 보고서를 저장할 수 있다.


리포트 디자이너

TFrDesign 컴포너트를 보고서가 존재하는 폼에 드롭할 경우, 리포트 디자이너(Report Designer)가 애플리케이션에 포함된다. 사용자들은 이를 이용해 새 보고서를 생성하거나 기존 보고서를 수정할 수 있다. 애플리케이션이 쿼리 빌더(query builder)를 포함한다는 점을 감안할 때 이것을 이용해 애플리케이션 최종 사용자에게 강력한 보고 솔루션을 만들어 줄 수 있겠다. 보고서 설계는 매우 간단하게 활성화된다:

procedure TForm1.BDesignClick(Sender: TObject);
  Var R : TFrReport;
begin
  R := SelectedReport;
  R.DesignReport;
end;


리포트 디자이너는 모달식(modal) 창이므로 디자이너가 닫힐 때까지 DesignReport 메소드는 리턴하지 않을 것이다.


마지막으로, 보고서 데이터를 내보내는 것이 가능하다. 이 기능은 보고서와 같은 폼에 내보내기 컴포넌트를 드롭함으로써 활성화된다. 그리고 미리보기 창에서 [Save] 버튼을 누르면 내보내기 포맷을 선택하도록 해준다:

  • Text. 보고서를 텍스트로 내보내어 가능한 한 포맷팅을 그대로 유지한다. 분명한 것은 이미지는 텍스트로 내보낼 수 없다는 점이다.
  • Html. 보고서를 HTML로 내보내어 가능한 한 포맷팅을 그대로 유지한다.
  • CSV. 보고서를 CSV (콤마로 구분된 값)로 내보낼 것이다. 모든 포맷팅은 손실되고 보고서 데이터만 내보내진다.


코드를 통해 보고서를 내보내기 위해서는 내보내기 컴포넌트 또한 폼에 드롭해야 한다. 아래 코드는 내보내기 포맷을 명시하기 위한 라디오그룹을 이용해 여러 포맷으로 데이터를 내보내는 방법을 보여준다:

procedure TForm1.BExportClick(Sender: TObject);
  Const HTMLFilter = 'HTML files|*.html';TeXTFilter = 'Text files|*.txt'
      CSVFilter = 'CSV files|*.csv'; AllFilter = '|All files|*.*';
  Var C : TClass; F : String; R : TfrReport;
begin
  R := SelectedReport;
  Case RGExport.ItemIndex of
    0 : begin
          C := TfrTextExportFilter;
          F := TextFilter;
        end;
    1 : begin
          C := TfrHTMExportFilter;
          F := HTMLFilter;
        end;
    2 : begin
          C := TfrCSVExportFilter;
          F := CSVFilter;
        end;
  end;

  SDExport.Filter := F + AllFilter;

  If SDExport.Execute then
     If R.PrepareReport then
       R.ExportTo(C,SDExport.filename)
     else
       ShowMessage('Prepare report failed !');
end;


case 문은 SDExport 저장 대화창을 위한 파일 필터 표현식과 내보내기 필터를 선택한다. 저장 대화창이 닫히고 나면 TFrReport 의 ExportTo 메소드가 호출된다. 이 때 두 개의 인수(argument)를 취한다: 첫 번째는 필터 클래스, 나머지는 내보내기가 저장될 파일명이다.