2007년 11월 7일 수요일

iText로 Table을 만들기

Create new Table by using iText Library

HtmlWriter나 RtfWriter2 를 이용하지 않고 테이블을 만들고 렌더링할려면 iText의 PdfPTable을 사용하는 것이 가장 무난하다.

아래에 그럼 가장 간단한 예로부터 차츰차츰 PdfPTable에 대하여 알아보도록 하자.

가령 아래 그림에서와 같은 Table을 만들려면 어떻게 코드가 구성되여야 할가?

사용자 삽입 이미지

실제 윗 그림에서와 같은 테이블을 만들기 위하여 드는 노력은 그다지 많지 않다..
아래에 그럼 실제 소스를 첨부하도록 하겠다.

소스열기

PdfPTable을 만들기 위하여 사용자는 필히 테이블에 들어가는 최대 컬럼의 갯수를 파라미터로 넘겨주어야 한다. 만약 컬럼 갯수가 0이면 RuntimeException이 발생한다.

테이블 넓이 및 정열방식 세팅하기
윗 소스 기초하에 아래는 테이블의 넓이와 정열방식을 변경해보도록 하자.
보다싶이 Table속의 Cell들의 정열방식중에서 왼쪽 정열방식이 기본정열 방식이다.
만약 정열을 Center로 바꾸고 싶으면 Element.ALIGN_CENTER를 이용하여 설정할 수가 있다.

table.setHorizontalAlignment(Element.ALIGN_CENTER);

테이블 넓이를 세팅함에 있어서 념두해 두어야 할 점은 테이블 넓이는 상대 넓이와 절대 넓이가 있다는 것이다.
테이블 절대 넓이를 세팅할려면 아래 두 메소드를 사용하면 된다.

PdfPTable table = new PdfPTable(3);
table.setTotalWidth(216f);
table.setLockedWidth(true);

실제 setTotalWidth에서 받는 값은 Float값이므로 뒤에 f를 써주어야 한다. 또한 절대 넓이이므로 꼭 LockedWidth를 true로 세팅해주어야 한다.

만약 테이블을 만들때 셀들의 넓이를 미리 알고 지정해주려면 어떻게 할것인가?
모두 두가지 방법이 있는데 하나는 셀을 만들고 나서 다시 넓이를 세팅하는 방식이고 다른 하나는 Table을 만들시 직접 셀의 갯수 및 매 셀의 넓이를 지정시켜서 만드는 방식이다.
첫 번째 방식은 쉬우므로 여기서 예제는 스킵하련다.
두 번째 방식에 대한 소스는 아래에 첨부하였다.

float[] widths1 = { 1f, 1f, 2f };
PdfPTable table = new PdfPTable(widths1);

여기서 1f, 1f, 2f 는 바로 셀 3개의 넓이를 미리 지정해 준것으로써 그 값은 퍼센테이지로 환산할 수 있다.즉 전체 테이블  넓이가 100%라면 첫 cell은 1/4 이므로 25%가 될것이고 두번째 셀 역시 25% 마지막 셀은 50%가 되겠다.

사용자 삽입 이미지

만약 테이블 처리 도중 셀의 넓이를 바꾸고 싶으면 setWidths 메소드를 사용하면 된다.

float[] widths2 = { 2f, 1f, 1f };
table.setWidths(widths2);

위 메소드를 실행하여 테이블을 만든 결과는 다음과 같다.

사용자 삽입 이미지

테이블 Border 및 다양한 스타일을 주기
실제 PdfPTable을 사용하다보면 좀 갑갑한 점 있다. 기존에 iText에서 지원하는 테이블류 클래스는 모두 3가지가 있다. 그것들로는 PdfPTable, Table, SimpleTable 인데 그중에서 PdfPTable이 실제 PDF에 가장 최적화 되여 만들어진 클래스이다. 하지만 PdfPTable 클래스를 살펴보면 이 클래스가 Element 인터페이스를 구현한것을 볼수 있다. 사실 여러가지 스타일을 테이블에 무난히 적용시키 위해서는 Table 클래스를 사용해야 한다. 하지만 Table 클래스는 PDF 문서에 최적화된 스타일의 테이블을 만들어주지 못하며 아직도 여러가지 버그가 존재한다. 때문에 아래는 Table 클래스가 아닌 PdfPTable 클래스를 이용하여 여러가지 스타일시트를 적용해보겠다.

PdfPTable 클래스를 살펴보면 Border를 세팅해주는 메소드자체가 없다. 그렇다면 어떻게 PdfPTable 클래스을 이용하여 Border가 2인 테이블을 만들것인가?
이를 가능하게 하기 위하여 우리는 별도의 Template이 필요하다. 또한 이런 Template을 우리는 PdfPTableEvent 인터페이스를 구현한 클래스에 넣어주어야 한다.
PdfPtableEvent 인터페이스를 보면

public void tableLayout(PdfPTable table, float widths[][], float heights[], int headerRows, int rowStart, PdfContentByte[] canvases);

tableLayour 메소드 하나만 달랑 있다. 사실상 이메소드는 테이블 렌더링이 끝나고 나서 호출이 되여진다. 실제 이 메소드를 통하여 추가한 텍스트와 그래프들은 테이블 렌더링이 끝난후 canvases 를 포함하고 있는 PdfContentByte속에 저장이 되여진다.
그럼 실제 PdfPTableEvent 인터페이스를 구현하여 테이블에 여러가지 모양을 내보자.

테이블 외곽에 두께가 1.5인 테두리를 넣어주는 것을 예로 들겠다.

먼저 PdfPTableEvents 라는 클래스를 하나 만들어보자.

소스열기

여기서 살펴 볼 곳은 딱 세곳이다.
첫째는 PdfPTableEvent 인터페이스를 구현했다는것이고, 둘째는 두께를 1.5로 설정한것이며 마지막 Border색상을 검정색으로 정한것이다.

다음 만든 PdfPTableEvents 클래스를 인스턴스화하여 실제 PdfPTable에 세팅한다.

PdfTableEvents event = new PdfTableEvents();
table.setTableEvent(event);


이러고 나면 실제 두께가 1.5인 테두리가 그려진 테이블을 볼수가 있다.

사용자 삽입 이미지

위 코드를 좀 더 개진하여 실제 굵기를 설정하려는 ROW의 인덱스 번호만 넣으면 굵기를 세팅해주는 기능을 추가할 수가 있다.

소스열기

그리고 위 클래스 인스턴스에서 필요한 인덱스 값만 배열로 넣으면 우리가 원하는 라인의 굵기를 재 설정할 수 가 있다.

실제 처리된 결과는 다음과 같다.

사용자 삽입 이미지

댓글 4개:

  1. 내용이 좀 빈약하나 아주 좋은 자료임에 틀림없네 ..... 자주들릴께 활성화되기를....

    답글삭제
  2. 시간상 상세한 부분까지 다룰수가 없네요...

    그래도 많이 지지해주시길 바랍니다. ^^

    답글삭제
  3. ㅋㅋㅋ 나도 왔다가여 행인지세 갔다가 .. ㅋㅋ 피터님글보고 웃겨서 댓글 남기고 감 ㅋㅋㅋㅋ ^.^

    답글삭제