2016-06-11 167 views
1

我創建的文檔確定列數。我想強制一些文本到最後一列。所謂「最後一欄」我的意思是,例如,如果我有ColumnDocumentRenderer定義爲具有3列的單頁,但我只有文本的一個專欄中,我還是要列3包含我的強制值。所以我想(預設了一個解決方案,別人讚賞),我需要機制來知道列號我在和強制分欄符。由於StackOverflow希望以問題的形式提供,(a)這些機制是什麼?和(b)什麼是替代方法?如何利用iText利用iText 7及其ColumnDocumentRenderer 7

問題How to skip text insertion point to the next column using iText?顯然問過類似的問題,但顯然是一個利用iText的早期版本;我沒有可以找到的ColumnText。

在此先感謝您的幫助。

+0

我會創建自己的渲染器。跟蹤的列的作爲[文檔】在完成(http://developers.itextpdf.com/content/itext-7-building-blocks/chapter-2-working-rootelement),更具體而言,我會覆蓋'updateCurrentArea()'方法並顯示'currentAreaNumber'。在添加進入第三列的內容並根據需要添加儘可能多的「AreaBreak」對象之前,我會檢查該數字。注意:由於某種原因,'currentAreaNumber'變量是'private'。我很想讓它「受保護」。 –

+0

我非常感謝鏈接到文檔。我通過itext站點跟蹤了各種鏈接,但從未找到特定於itext7的文檔。再次感謝。 – OldAndTired

+0

完美工作 – OldAndTired

回答

1

我是從我的電話接聽昨天,但現在,我有機會獲得一臺電腦,我改變ColumnDocumentRenderer這樣的:

public class ColumnDocumentRenderer extends DocumentRenderer { 

    protected Rectangle[] columns; 
    protected int nextAreaNumber; 

    public ColumnDocumentRenderer(Document document, Rectangle[] columns) { 
     super(document); 
     this.columns = columns; 
    } 

    public ColumnDocumentRenderer(Document document, boolean immediateFlush, Rectangle[] columns) { 
     super(document, immediateFlush); 
     this.columns = columns; 
    } 

    @Override 
    protected LayoutArea updateCurrentArea(LayoutResult overflowResult) { 
     if (overflowResult != null && overflowResult.getAreaBreak() != null && overflowResult.getAreaBreak().getType() != AreaBreakType.NEXT_AREA) { 
      nextAreaNumber = 0; 
     } 
     if (nextAreaNumber % columns.length == 0) { 
      super.updateCurrentArea(overflowResult); 
     } 
     return (currentArea = new LayoutArea(currentPageNumber, columns[nextAreaNumber++ % columns.length].clone())); 
    } 

    public int getNextAreaNumber() { 
     return nextAreaNumber; 
    } 
} 

的變化將是iText的7.0.1,但你可以使用這個代碼在你自己的渲染器中。

現在可以使用此渲染器是這樣的:

public void createPdf(String dest) throws IOException { 
    OutputStream fos = new FileOutputStream(dest); 
    PdfWriter writer = new PdfWriter(fos); 
    PdfDocument pdf = new PdfDocument(writer); 
    Document document = new Document(pdf); 

    float offSet = 36; 
    float gutter = 23; 
    float columnWidth = (PageSize.A4.getWidth() - offSet * 2)/3 - gutter * 2; 
    float columnHeight = PageSize.A4.getHeight() - offSet * 2; 
    Rectangle[] columns = { 
     new Rectangle(offSet, offSet, columnWidth, columnHeight), 
     new Rectangle(offSet + columnWidth + gutter, offSet, columnWidth, columnHeight), 
     new Rectangle(offSet + 2 * (columnWidth + gutter), offSet, columnWidth, columnHeight)}; 
    ColumnDocumentRenderer renderer = new ColumnDocumentRenderer(document, columns); 
    document.setRenderer(renderer); 

    for (int i = 0; i < 50; i++) { 
     document.add(new Paragraph("Hello World")); 
    } 
    while (renderer.getNextAreaNumber() % 3 != 0) 
     document.add(new AreaBreak()); 
    document.add(new Paragraph("Third column")); 
    document.add(new AreaBreak()); 
    for (int i = 0; i < 80; i++) { 
     document.add(new Paragraph("Hello World")); 
    } 
    while (renderer.getNextAreaNumber() % 3 != 0) 
     document.add(new AreaBreak()); 
    document.add(new Paragraph("Third column")); 
    document.add(new AreaBreak()); 
    for (int i = 0; i < 10; i++) { 
     document.add(new Paragraph("Hello World")); 
    } 
    while (renderer.getNextAreaNumber() % 3 != 0) 
     document.add(new AreaBreak()); 
    document.add(new Paragraph("Third column")); 
    document.close(); 

} 

中第一列的索引0和下一個區域數爲1,第二列具有索引1和下一個區域編號是2,所以上。

這意味着,你可以檢查並轉到第三列這樣的頁面上。

while (renderer.getNextAreaNumber() % 3 != 0) 
    document.add(new AreaBreak()); 
+0

解耦來自實現細節的新的'ColumnDocumentRenderer'方法,讓它返回* current *區域號並將其命名爲'getAreaNumber'是否更有意義?畢竟,通常用戶會想知道他在哪一列,而不是哪一列是下一個。 (是的,很容易從另一箇中推導出一個,但是有一種方法可以讓我獲得當前專欄比直接用於獲取下一篇更直觀。) – mkl

+0

我想到了這個,我也有同樣的想法,但後來我發現一些讓我決定去「nextAreaNumber」的參數。我已經忘記了這些論點,但我記得他們與分頁的效果有關。 –