2014-03-03 2 views
0

나는 이것에 대한 해답을 찾고 있었지만 좋은 지침서를 찾을 수 없다. 나는 pdf를 생성하기 위해 자바 itext를 사용하고있다. 나는 약 2 페이지를 먹는 50 개 이상의 행을 인쇄하는 테이블을 가지고있다. 목록 인쇄를 계속하기 전에 이전 페이지의 마지막 5 행을 다음 페이지로 인쇄해야합니다.다음 페이지에서 테이블의 마지막 5 행을 반복하는 방법은 무엇입니까?

Example: row 31 row 32 row 33 row 34 row 35 row 36 --end of page 1-- row 32 row 33 row 34 row 35 row 36 row 37

이 작업을 수행하는 방법에 대한 어떤 생각?

Currently it prints like this: row 35 row 36 --end of page 1-- row 37 row 38

코드 : (시작 루프에 초점 그 헤더를 신경 쓰지)

PdfPTable table = new PdfPTable(4); 
table.setWidthPercentage(97); 
table.setWidths(new float[] {10, 45, 25, 25}); 

PdfPCell c1 = new PdfPCell(new Phrase("Logo", FontFactory.getFont(FontFactory.TIMES_ROMAN, 14))); 
c1.setPadding(5); 
c1.setHorizontalAlignment(Element.ALIGN_LEFT); 
c1.setVerticalAlignment(Element.ALIGN_CENTER); 
c1.setBorder(0); 
c1.setColspan(4); 
table.addCell(c1); 

c1 = new PdfPCell(new Phrase("09/01/2013 - 09/15/2013", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12))); 
c1.setPadding(5); 
c1.setHorizontalAlignment(Element.ALIGN_LEFT); 
c1.setVerticalAlignment(Element.ALIGN_CENTER); 
c1.setBorder(0); 
c1.setColspan(4); 
c1.setPaddingBottom(20); 
table.addCell(c1); 

//start header 
c1 = new PdfPCell(new Phrase(" ", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12))); 
c1.setPaddingBottom(5); 
c1.setHorizontalAlignment(Element.ALIGN_LEFT); 
c1.setBackgroundColor(WebColors.getRGBColor("#99CCFF")); 
c1.setBorder(1); 
table.addCell(c1); 

c1 = new PdfPCell(new Phrase("Name", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12))); 
c1.setPaddingBottom(5); 
c1.setHorizontalAlignment(Element.ALIGN_LEFT); 
c1.setBackgroundColor(WebColors.getRGBColor("#99CCFF")); 
c1.setBorder(1); 
table.addCell(c1); 

c1 = new PdfPCell(new Phrase("Number", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12))); 
c1.setPaddingBottom(5); 
c1.setHorizontalAlignment(Element.ALIGN_LEFT); 
c1.setBackgroundColor(WebColors.getRGBColor("#99CCFF")); 
c1.setBorder(1); 
table.addCell(c1); 

c1 = new PdfPCell(new Phrase("Amount", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12))); 
c1.setPaddingBottom(5); 
c1.setHorizontalAlignment(Element.ALIGN_RIGHT); 
c1.setBackgroundColor(WebColors.getRGBColor("#99CCFF")); 
c1.setBorder(1); 
table.addCell(c1); 
//end header 

//start for loop 
for(int a=0; a<50; a++) 
{ 
    int border=0; 
    if(a%5==0) 
    {border=1;} 

    c1 = new PdfPCell(new Phrase((a+1)+"", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12))); 
    c1.setHorizontalAlignment(Element.ALIGN_LEFT); 
    c1.setBorder(border); 
    c1.setPaddingBottom(5); 
    table.addCell(c1); 

    c1 = new PdfPCell(new Phrase("Last Name, First Name", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12))); 
    c1.setHorizontalAlignment(Element.ALIGN_LEFT); 
    c1.setBorder(border); 
    c1.setPaddingBottom(5); 
    table.addCell(c1); 

    c1 = new PdfPCell(new Phrase("1", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12))); 
    c1.setHorizontalAlignment(Element.ALIGN_CENTER); 
    c1.setBorder(border); 
    c1.setPaddingBottom(5); 
    table.addCell(c1); 

    c1 = new PdfPCell(new Phrase("1", FontFactory.getFont(FontFactory.TIMES_ROMAN, 12))); 
    c1.setHorizontalAlignment(Element.ALIGN_RIGHT); 
    c1.setBorder(border); 
    c1.setPaddingBottom(5); 
    table.addCell(c1); 


} 
//end for loop 

subCatPart.add(table); 
+0

@Sandeep은 : 이미를 발견하고는 내 질문에 –

+0

@Sandeep 추가 코드에 응답하지 않습니다. –

+0

프로그램을 실행할 때마다 테이블의 크기가 항상 같거나 매개 변수에 따라 다릅니다. –

답변

1

당신은 document.add()를 사용하여이를 달성 할 수없는; 대신 writeSelectedRows() 메소드를 사용하여 특정 행을 작성해야합니다. 예를 들어 RepeatLastRows 메소드를 참조하십시오.

이 예제에서는 99 개의 행이있는 테이블이 있습니다. 이 테이블을 문서에 추가하려면 document.add()을 사용하면 3 페이지가 소요되고 세 번째 페이지에는 3 행만 표시됩니다. 이 페이지에서 5 행을 표시하고 이전 페이지에서 2 행을 반복합니다.

우리는 여백이 36 인 A4 페이지가 있다고 가정합니다. 즉, 사용 가능한 표면은 730pt로 523을 측정합니다.

// we create a table that spans the width of the page and that has 99 rows 
PdfPTable table = new PdfPTable(1); 
table.setTotalWidth(523); 
for (int i = 1; i < 100; i++) 
    table.addCell("row " + i); 

총 너비를 설정합니다. 너비를 지정하지 않고 writeSelectedRows()을 사용하면 예외가 발생합니다.

while (true) { 
    // available height of the page 
    float available_height = 770; 
    // how many rows fit the height? 
    while (available_height > 0 && currentRow < totalRows) { 
     available_height -= table.getRowHeight(currentRow++); 
    } 
    // we stop as soon as all the rows are counted 
    if (currentRow == totalRows) 
     break; 
    // we draw part the rows that fit the page and start a new page 
    table.writeSelectedRows(currentRowStart, --currentRow, 36, 806, canvas); 
    document.newPage(); 
    currentRowStart = currentRow; 
} 

이 루프에서, 우리가 이미 두 페이지를 채운 : 우리는 한 낮은 totalRows보다 currentRow로 계속 루프를 만듭니다

PdfContentByte canvas = writer.getDirectContent(); 
int currentRowStart = 0; 
int currentRow = 0; 
int totalRows = table.getRows().size(); 

:

우리는 몇 가지 매개 변수를 초기화 : 하나는 행 1에서 48을 보여주고, 다른 하나는 49에서 96까지의 행을 보여줍니다. 루프에서 빠져 나오면 currentRow는 99이고 currentRowStart는 96입니다 (이것은 행 97의 행 인덱스입니다). 즉, 행 97, 98 및 99 만 표시됩니다. 우리는 5 행을 표시하고자하므로 currentRow의 값을 적절히 변경합니다.
if (currentRow - currentRowStart < 5) 
    currentRowStart = currentRow - 5; 
table.writeSelectedRows(currentRowStart, currentRow, 36, 806, canvas); 

하는 결과 PDF에서 봐 주시기 바랍니다, 당신은 세 번째 페이지는 행 95 (이미 2 페이지에 표시 된 행)로 시작하는 것을 볼 수 있습니다.

업데이트 : 최종 페이지에 행이 몇 개없는 고아가있는 경우에만 행을 반복해야한다고 생각한다는 점에서 질문을 잘못 해석했습니다. 실제 요구 사항은 이고 항상은 테이블이 분할 될 때마다 5 행을 반복합니다.

원래 예제를 약간 업데이트했습니다. RepeatLastRows2을 참조하십시오. currentRowStart의 값을 변경하여 시작이 5 행으로 돌아가지만 currentRow 값을 업데이트하는 것을 잊었습니다. 따라서 사용 가능한 높이에서 충분한 공간을 뺍니다.

5 개 행 (또는 그 미만)이 단일 페이지에 맞으면 동일한 5 행을 반복하여 반복하여 무한 루프 (또는 ArrayIndexOutOfBoundsExceptions)를 삽입하지 않도록하십시오.

+0

게시자가 귀하의 게시물을 설명하는 방식에서, 나는 이것이 (사소한 변화를 통해) 찾고있는 것이라고 생각합니다. 나는 잠을 자고 난 후에 이것에 대한 최신 정보를 줄 것이다. –

+0

나는 코드에 약간의 변경을 가했다. if (currenRow - currentRowStart <5) 조건을 제거하고 -5를 currentRowStart = currentRow에 추가했습니다 (currentRowStart = currentRow가 됨). 코드를 실행하면 93 행과 94 행의 일부가 2 페이지에 인쇄됩니다. 어떤 생각이 잘못 됐나요? –

+0

무엇이 잘못 되었나요? 당신이 그것을 부러 뜨 ;-) itextpdf.com에 게시 된 원본 샘플을 다운로드하십시오; 문제를 재현 할 수 있도록 샘플을 수정하고 (예 : 질문에) 전체 샘플을 게시하십시오. 변경 한 내용 만 도움이되지 않는다고 말하면됩니다 (변경 방법은 분명하지 않습니다). 또한 : iText의 어떤 버전을 사용하고 있습니까? –

0

최근에 도입 된 PdfPTableEventAfterSplit은 테이블을 분할해야 할 때 트리거됩니다. 현재 페이지가 렌더링 된 후에 트리거되지만 다음 페이지가 시작되기 전에 트리거됩니다. 이를 사용하여 다음 페이지에서 반복 할 행을 복제 할 수 있습니다.

class RepeatSplitEvent extends PdfPTableEventForwarder { 
    @Override 
    public void afterSplitTable(PdfPTable table, PdfPRow startRow, int startIdx) { 
     for (int i = startIdx - 5; i < startIdx; i++) { 
      table.getRows().add(0, table.getRow(i)); 
     } 
    } 
} 

그리고

// ... 
PdfPTable table = new PdfPTable(4); 
table.setTableEvent(new RepeatSplitEvent()); 
// ... 
관련 문제