사용자 도구

사이트 도구


android:pdfdocument:drawingtagble
drawingtagble

소개

다음과 같이 표를 그리고, 데이터베이스에서 가져온 값을 표에 넣을 것이다.

tabledrawing

표 그리기

1. 개념

표를 그릴려면 어떻게 해야 할까? 여러가지 방법이 있을 것인데 하나는 큰 박스를 넣은 후 그 안에 선을 그리는 방법이 있을 것이다. 또다른 방법은 박스를 여러개 그리는 것이다. 이를테면 한 줄에 2개의 칸이 있는 2×1 표를 그린다고 해보자. 그러면 긴 박스와 작은 박스를 겹쳐서 그리면 될 것이다. 나는 선을 그리는 방법보다는 박스를 겹치는 방법을 선택했다.

왜냐하면 위의 소개 그림에서도 보듯이 셀에 음영을 넣는 경우가 생길텐데, 음영을 넣으려면 이 역시 박스를 그리는 방식으로 진행된다. 따라서 선을 그리고 음영을 넣는다는 것은 중복된 일을 하는 것가 마차가지가 되는 것이다. 그리고 박스를 중첩하는 방식으로 표를 만들면, 각 셀 안에 들어간 텍스트의 위치를 계산하는 것도 쉽다.

2. 셀 그리기

표를 그리려면 기준점이 있어야 한다. 좌측 상단을 기준점으로 잡는 것이 통상적이고, 가장 이해하기 쉬울 것이다. 좌측 상단을 기준으로 2개의 박스를 겹쳐서 1줄짜리 표를 그리면 다음과 같이 될 것이다.

table drawing

따라서 다음의 코드가 될 것이다.

        /** 변수 **/
        val cellHeight = 30   // Row Height : 40
        val columnWidth = 180f   // 내부선
        val vcOffset = 4f //  세로 중간을 맞추기 위한 오프셋
 
        // Rect
        canvas.drawRect(currentPOS.X.toFloat(), currentPOS.Y.toFloat(),  endOfBody, currentPOS.Y.toFloat() + cellHeight, linePaint)  // 첫쨰 줄
        canvas.drawRect(currentPOS.X.toFloat(), currentPOS.Y.toFloat(),  currentPOS.X.toFloat() + columnWidth, currentPOS.Y.toFloat() + cellHeight, linePaint)  // 제목박스

여기서 endOfBody는 본문 영역의 너비를 말한다. 사전에 다음과 같이 정의되었다.

    // 여백
    val marginTop = 42
    val marginBottom = 50
    val marginLeft = 47
    val marginRight = 48
 
    // end of 본문
    val endOfBody = (PDF_PAGE_WIDTH - marginRight).toFloat()

이러한 셀들을 여러개를 연결하면 표가 될 것이다.

3. 셀안에 글자를 집어 넣기

각 셀의 좌측상단을 기준점으로 잡았으므로 글자는 이를 기준으로 상대 좌표를 구하면 된다.

만약 셀안에 가로정렬을 한다고 해보자. 셀 안의 가운데 점을 잡아야 하므로

가로좌표는 기준점 + (cellwidth) / 2가 될 것이다. 세로좌표는 기준점 + (cellHeight) / 2가 될 것이다.

따라서 셀 안에 글자를 집어 넣는 것은 다음 코드가 될 것이다.

        // Text
        canvas.drawText(header, currentPOS.X.toFloat() + columnWidth / 2, currentPOS.Y.toFloat() + cellHeight / 2 + vcOffset, cellHeaderLight)
        canvas.drawText(body, currentPOS.X.toFloat() + columnWidth + (endOfBody - (currentPOS.X + columnWidth)) / 2, currentPOS.Y.toFloat() + cellHeight / 2 + vcOffset, cellBody)

참고로 세로좌표의 경우에는 오프셋을 추가하였는데, 이는 글자의 베이스라인은 좌측하단에 있기 때문이다.

안드로이드의 폰트메트릭스에 대해서는 이전 포스팅을 참고하라.

결론

이 포스팅의 서두부분에 나온 표를 그린다면 다음의 코드를 사용하면 될 것이다.

tablePlaintiff.kt
// 표 : 고소인
fun tablePlaintiff(canvas: Canvas) {
 
    /** 변수 **/
    val cellHeight = 30   // Row Height : 40
    val columnWidth = 60f   // 내부선
    val secondColumn = 260f // 두번쨰 열
    val vcOffset = 4f //  세로 중간을 맞추기 위한 오프셋
 
    plaintiffList?.forEach() {
        // 첫째 행
        // Rect
        canvas.drawRect(currentPOS.X.toFloat(), currentPOS.Y.toFloat(),  endOfBody, currentPOS.Y.toFloat() + cellHeight, linePaint)  // 첫쨰 줄
        canvas.drawRect(currentPOS.X.toFloat(), currentPOS.Y.toFloat(),  currentPOS.X.toFloat() + columnWidth, currentPOS.Y.toFloat() + cellHeight, cellFill)  // 제목박스
        canvas.drawRect(currentPOS.X.toFloat() + secondColumn, currentPOS.Y.toFloat(),  currentPOS.X.toFloat() + secondColumn + columnWidth, currentPOS.Y.toFloat() + cellHeight, cellFill)  // 두번째 제목박스
 
        // Text
        canvas.drawText("이   름", currentPOS.X.toFloat() + columnWidth / 2, currentPOS.Y.toFloat() + cellHeight / 2 + vcOffset , cellHeader)
        canvas.drawText(it.pName, currentPOS.X.toFloat() + columnWidth + (secondColumn - columnWidth) / 2, currentPOS.Y.toFloat() + cellHeight / 2 + vcOffset, cellBody)
        canvas.drawText("주민번호", currentPOS.X.toFloat() + secondColumn + columnWidth / 2, currentPOS.Y.toFloat() + cellHeight / 2 + vcOffset, cellHeader)   // 2번쨰 칸
        canvas.drawText(it.socialNumber, currentPOS.X.toFloat() + secondColumn + columnWidth + (endOfBody - (currentPOS.X + secondColumn + columnWidth)) / 2, currentPOS.Y.toFloat() + cellHeight / 2 + vcOffset, cellBody)
 
 
        // 둘재 행
        // Rect
        canvas.drawRect(currentPOS.X.toFloat(), currentPOS.Y.toFloat() + cellHeight,  endOfBody, currentPOS.Y.toFloat() + cellHeight * 2, linePaint)  // 둘쨰 줄
        canvas.drawRect(currentPOS.X.toFloat(), currentPOS.Y.toFloat() + cellHeight,  currentPOS.X.toFloat() + columnWidth, currentPOS.Y.toFloat() + cellHeight * 2, cellFill)  // 제목박스
 
        // Text
        canvas.drawText("주  소", currentPOS.X.toFloat() + columnWidth / 2, currentPOS.Y.toFloat() + cellHeight * 1 + cellHeight / 2 + vcOffset, cellHeader)
        canvas.drawText(it.pAddress, currentPOS.X.toFloat() + columnWidth + (endOfBody - (currentPOS.X + columnWidth)) / 2, currentPOS.Y.toFloat() + cellHeight * 1 + cellHeight / 2 + vcOffset, cellBody)
 
        // 셋쨰 행
        // Rect
        canvas.drawRect(currentPOS.X.toFloat(), currentPOS.Y.toFloat() + cellHeight * 2,  endOfBody, currentPOS.Y.toFloat() + cellHeight * 3, linePaint)  // 셋쨰 줄
        canvas.drawRect(currentPOS.X.toFloat(), currentPOS.Y.toFloat() + cellHeight * 2,  currentPOS.X.toFloat() + columnWidth, currentPOS.Y.toFloat() + cellHeight * 3, cellFill)  // 제목박스
 
        // Text
        canvas.drawText("연 락 처", currentPOS.X.toFloat() + columnWidth / 2, currentPOS.Y.toFloat() + cellHeight * 2 + cellHeight / 2 + vcOffset, cellHeader)    // 제목
        canvas.drawText(it.pPhoneNumber, currentPOS.X.toFloat() + columnWidth + (endOfBody - (currentPOS.X + columnWidth)) / 2, currentPOS.Y.toFloat() + cellHeight * 2 + cellHeight / 2 + vcOffset, cellBody)  // 내용
 
        // 아래 여백
        totalPOS += POS(0, cellHeight * 3 + 20)
        currentPOS += POS(0, cellHeight * 3 + 20)
    }?:{
 
        canvas.drawRect(currentPOS.X.toFloat(), currentPOS.Y.toFloat(),  endOfBody, currentPOS.Y.toFloat() + cellHeight, linePaint)  // 첫쨰 줄
        canvas.drawText("당사자 정보가 없습니다. 당사자를 추가했는지 확인하세요!", currentPOS.X.toFloat() + endOfBody / 2, currentPOS.Y.toFloat() + cellHeight / 2 + vcOffset , cellHeader)
 
        // 아래 여백
        linefeed()
    }
 
}
로그인하면 댓글을 남길 수 있습니다.

android/pdfdocument/drawingtagble.txt · 마지막으로 수정됨: 2024/12/11 01:32 저자 이거니맨