如何使用iTextSharp消除多列中的空白? [英] How can you eliminate white-space in multiple columns using iTextSharp?

查看:86
本文介绍了如何使用iTextSharp消除多列中的空白?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在两列中的页面上添加一个文本段落.我知道MultiColumnText已被删除.我知道我可以创建第1列,并写入它;如果还有更多文本,则创建第2列,并写入它.如果还有更多文本,请转到下一页并重复.

I'd like to add a Paragraph of text to pages in 2 columns. I understand that MultiColumnText has been eliminated. I know I can create column 1, write to it, and if there is more text create column 2 and write to it. If there is still more text, go to the next page and repeat.

但是我总是以以下两种情况结尾:

However I always end up with either:

  1. 左栏中孤立的一长段文本.
  2. 左列全部用完,右列部分用完.

如何在减少空白的情况下将内容格式化为2列,例如压缩列,以便以2个等长的完整列结尾?

How can I format my content in 2 columns while reducing white space, such as compressing the columns so I end with 2 full columns of equal length?

谢谢!

推荐答案

您应该将列添加两次,一次是在模拟模式下,一次是在真实模式下.

You should add your column twice, once in simulation mode and once for real.

我修改了 ColumnTextParagraphs 示例,以显示模拟模式的含义.看看 ColumnTextParagraphs2 示例:

I have adapted the ColumnTextParagraphs example to show what is meant by simulation mode. Take a look at the ColumnTextParagraphs2 example:

我们在模拟模式下添加该列以获得该列所需的总高度.这可以通过以下方法完成:

We add the column in simulation mode to obtain the total height needed for the column. This is done in the following method:

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

我们在添加左右列时使用此高度:

We use this height when we add the left and right column:

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();
}

这是我们检查高度的方法:

This is how we check the height:

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

如您所见,只要两列的高度都小于剩余高度,我们就会添加整列.添加列后,我们将调整剩余高度.一旦高度低于to列的高度,我们就会调整第一列的高度.

As you can see, we add the full columns as long as the height of both columns is smaller than the remaining height. When columns are added, we adjust the remaining height. As soon as the height is lower than the height of to columns, we adapt the height of the first column.

请注意,我们使用ERROR_MARGIN是因为除以二通常会导致第二列比第一列多一行的情况.反之则更好.

Note that we work with an ERROR_MARGIN because dividing by two often leads to a situation where the second column has one line more than the first column. It is better when it's the other way around.

这是您要求的完整示例:

This is the full example at your request:

/**
 * 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;
    }
}

这篇关于如何使用iTextSharp消除多列中的空白?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆