2015-03-31 3 views
0

Я хотел бы добавить абзац текста на страницы в 2 столбцах. Я понимаю, что MultiColumnText был удален. Я знаю, что могу создать столбец 1, написать ему, и если есть больше текста, создайте столбец 2 и напишите ему. Если текст еще больше, перейдите на следующую страницу и повторите.Как устранить пустое пространство в нескольких столбцах с помощью iTextSharp?

Однако я всегда в конечном итоге либо:

  1. длинный кусок текста сиротского в левой колонке.
  2. полная левая колонка и частично используется правая колонка.

Как я могу отформатировать свой контент в 2 столбцах при уменьшении пробелов, например, сжимать столбцы, поэтому я заканчиваю на 2 полных столбца одинаковой длины?

Спасибо!

ответ

1

Вы должны добавить свой столбец дважды, один раз в режиме симуляции и один раз для реального.

Я применил пример ColumnTextParagraphs, чтобы показать, что подразумевается под режимом симуляции. Посмотрите на пример:

enter image description here

Мы добавляем колонку в режиме симуляции, чтобы получить общую высоту, необходимую для столбца. Это делается следующим способом:

public float getNecessaryHeight(ColumnText ct) throws DocumentException { 
    ct.setSimpleColumn(new Rectangle(0, 0, COLUMN_WIDTH, -500000)); 
    ct.go(true); 
    return -ct.getYLine(); 
} 

Мы используем эту высоту, когда мы добавим левую и правую колонку:

Rectangle left; 
float top = COLUMNS[0].getTop(); 
float middle = (COLUMNS[0].getLeft() + COLUMNS[1].getRight())/2; 
float columnheight; 
int status = ColumnText.START_COLUMN; 
while (ColumnText.hasMoreText(status)) { 
    if (checkHeight(height)) { 
     columnheight = COLUMNS[0].getHeight(); 
     left = COLUMNS[0]; 
    } 
    else { 
     columnheight = (height/2) + ERROR_MARGIN; 
     left = new Rectangle(
      COLUMNS[0].getLeft(), 
      COLUMNS[0].getTop() - columnheight, 
      COLUMNS[0].getRight(), 
      COLUMNS[0].getTop() 
     ); 
    } 
    // left half 
    ct.setSimpleColumn(left); 
    ct.go(); 
    height -= COLUMNS[0].getTop() - ct.getYLine(); 
    // separator 
    canvas.moveTo(middle, top - columnheight); 
    canvas.lineTo(middle, top); 
    canvas.stroke(); 
    // right half 
    ct.setSimpleColumn(COLUMNS[1]); 
    status = ct.go(); 
    height -= COLUMNS[1].getTop() - ct.getYLine(); 
    // new page 
    document.newPage(); 
} 

Это, как мы проверяем высоту:

public boolean checkHeight(float height) { 
    height -= COLUMNS[0].getHeight() + COLUMNS[1].getHeight() + ERROR_MARGIN; 
    return height > 0; 
} 

Как вы можете видеть, мы добавляем полные столбцы, если высота обоих столбцов меньше оставшейся высоты. Когда столбцы добавляются, мы корректируем оставшуюся высоту. Как только высота будет ниже высоты столбцов, мы адаптируем высоту первого столбца.

Обратите внимание, что мы работаем с ERROR_MARGIN, потому что разделение на два часто приводит к ситуации, когда второй столбец имеет одну строку больше, чем первый столбец. Лучше, когда все наоборот.

Это полный пример по вашему желанию:

/** 
* Example written by Bruno Lowagie in answer to: 
* http://stackoverflow.com/questions/29378407/how-can-you-eliminate-white-space-in-multiple-columns-using-itextsharp 
*/ 
package sandbox.objects; 

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 

import com.itextpdf.text.Document; 
import com.itextpdf.text.DocumentException; 
import com.itextpdf.text.Paragraph; 
import com.itextpdf.text.Rectangle; 
import com.itextpdf.text.pdf.ColumnText; 
import com.itextpdf.text.pdf.PdfContentByte; 
import com.itextpdf.text.pdf.PdfWriter; 

public class ColumnTextParagraphs2 { 

    public static final String DEST = "results/objects/column_paragraphs2.pdf"; 

    public static final String TEXT = "This is some long paragraph that will be added over and over again to prove a point."; 
    public static final float COLUMN_WIDTH = 254; 
    public static final float ERROR_MARGIN = 16; 
    public static final Rectangle[] COLUMNS = { 
     new Rectangle(36, 36, 36 + COLUMN_WIDTH, 806), 
     new Rectangle(305, 36, 305 + COLUMN_WIDTH, 806) 
    }; 

    public static void main(String[] args) throws IOException, DocumentException { 
     File file = new File(DEST); 
     file.getParentFile().mkdirs(); 
     new ColumnTextParagraphs2().createPdf(DEST); 
    } 

    public void createPdf(String dest) throws IOException, DocumentException { 
     // step 1 
     Document document = new Document(); 
     // step 2 
     PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest)); 
     // step 3 
     document.open(); 
     // step 4 
     PdfContentByte canvas = writer.getDirectContent(); 
     ColumnText ct = new ColumnText(canvas); 
     addContent(ct); 
     float height = getNecessaryHeight(ct); 
     addContent(ct); 
     Rectangle left; 
     float top = COLUMNS[0].getTop(); 
     float middle = (COLUMNS[0].getLeft() + COLUMNS[1].getRight())/2; 
     float columnheight; 
     int status = ColumnText.START_COLUMN; 
     while (ColumnText.hasMoreText(status)) { 
      if (checkHeight(height)) { 
       columnheight = COLUMNS[0].getHeight(); 
       left = COLUMNS[0]; 
      } 
      else { 
       columnheight = (height/2) + ERROR_MARGIN; 
       left = new Rectangle(
        COLUMNS[0].getLeft(), 
        COLUMNS[0].getTop() - columnheight, 
        COLUMNS[0].getRight(), 
        COLUMNS[0].getTop() 
       ); 
      } 
      // left half 
      ct.setSimpleColumn(left); 
      ct.go(); 
      height -= COLUMNS[0].getTop() - ct.getYLine(); 
      // separator 
      canvas.moveTo(middle, top - columnheight); 
      canvas.lineTo(middle, top); 
      canvas.stroke(); 
      // right half 
      ct.setSimpleColumn(COLUMNS[1]); 
      status = ct.go(); 
      height -= COLUMNS[1].getTop() - ct.getYLine(); 
      // new page 
      document.newPage(); 
     } 
     // step 5 
     document.close(); 
    } 

    public void addContent(ColumnText ct) { 
     for (int i = 0; i < 35; i++) { 
      ct.addElement(new Paragraph(String.format("Paragraph %s: %s", i, TEXT))); 
     } 
    } 

    public float getNecessaryHeight(ColumnText ct) throws DocumentException { 
     ct.setSimpleColumn(new Rectangle(0, 0, COLUMN_WIDTH, -500000)); 
     ct.go(true); 
     return -ct.getYLine(); 
    } 

    public boolean checkHeight(float height) { 
     height -= COLUMNS[0].getHeight() + COLUMNS[1].getHeight() + ERROR_MARGIN; 
     return height > 0; 
    } 
} 
+0

У меня возникли проблемы с открытием ссылки предоставленной вами, так что я не уверен, что метод GetHeight() будет делать. Мои комментарии состоят в том, что: 1) это предполагает, что вершина столбцов всегда находится в одном и том же положении. Что делать, если столбцы должны начинаться наполовину вниз по первой странице? и 2) выглядит, что вы начинаете новую страницу с каждой итерации. Это все равно оставит пустое место, допустим, если на последней странице столбцы были только 1 ". –

+0

Я просто проверил ссылки. Они работают для меня. Все ответы, необходимые для создания полного примера, находятся в ответе, но я 'll copy полностью вставляет полный код. Метод 'getHeight()' получает высоту 'Rectangle', например' COLUMN [0] '. –

+0

Вопрос 1 не имеет значения. Вы можете определить' COLUMN [0] 'и' COLUMN [1] 'любым способом, который вы хотите. Вопрос 2 странный: когда у вас есть серия страниц формата А4, вам нужна ситуация, когда у вас внезапно появляется гораздо меньшая страница?Это странно, но не невозможно: поскольку вы знаете «высоту», вы можете проверить оставшуюся высоту и изменить размер страницы * перед тем, как запускать новую страницу. –