【问题标题】:Divide page in 2 parts so we can fill each with different source将页面分成两部分,以便我们可以用不同的来源填充每个部分
【发布时间】:2015-02-13 14:57:15
【问题描述】:

我需要创建一个用户指南,我必须将内容以 2 种不同的语言放在同一页面上。所以页面的前半部分是英文,而后半部分是法文。 (将来他们可能还会要求第三种语言,但最多 3 种)。所以每个页面会有 2 个块。如何在 java 中使用 iTextPDF 实现这一点?


更新

以下是更深入地了解问题的结构。

【问题讨论】:

  • 您是否尝试过使用ColumnText
  • @BrunoLowagie 感谢您抽出宝贵时间,先生,我要求页面结构是行对齐的。为了获得更多洞察力,我添加了一个示例。请提出建议。
  • 我看了这个例子,我必须重复一遍:你试过用ColumnText吗?因为如果我想要你在你需要的图形表示中描述的输出,这就是我的工作方式。

标签: java pdf pdf-generation itext itextpdf


【解决方案1】:

如果我正确理解您的问题,您需要创建如下内容:

在此屏幕截图中,您可以看到凯撒《高卢战争评论》第一本书的第一部分。 Gallia omnia est divisa in partes tres, 本文档中的每一页也是如此:上半部分显示拉丁文文本,中部显示英文文本,下半部分显示法文文本.如果您阅读本文,您会发现像我这样的比利时人被认为是最勇敢的人(尽管我们并不像人们希望的那样文明)。如果您想查看 PDF,请参阅 three_parts.pdf

此 PDF 是使用 ThreeParts 示例创建的。在这个例子中,我有 9 个文本文件:

Liber 是书籍的拉丁词,因此所有文件都是来自第一本书的 sn-ps,更具体地说,是拉丁文、英文和法文的第 1、2 和 3 节。

这就是我定义语言的方式以及每种语言的矩形:

public static final String[] LANGUAGES = { "la", "en", "fr" };
public static final Rectangle[] RECTANGLES = {
    new Rectangle(36, 581, 559, 806),
    new Rectangle(36, 308.5f, 559, 533.5f),
    new Rectangle(36, 36, 559, 261) };

在我的代码中,我循环遍历不同的部分,并为每种语言创建一个 ColumnText 对象:

PdfContentByte cb = writer.getDirectContent();
ColumnText[] columns = new ColumnText[3];
for (int section = 1; section <= 3; section++) {
    for (int la = 0; la < 3; la++) {
        columns[la] = createColumn(cb, section, LANGUAGES[la], RECTANGLES[la]);
    }
    while (addColumns(columns)) {
        document.newPage();
        for (int la = 0; la < 3; la++) {
            columns[la].setSimpleColumn(RECTANGLES[la]);
        }
    }
    document.newPage();
}

如果您检查内部循环的主体,您会看到我首先定义了三个ColumnText 对象,每种语言一个:

public ColumnText createColumn(PdfContentByte cb, int i, String la, Rectangle rect)
    throws IOException {
    ColumnText ct = new ColumnText(cb);
    ct.setSimpleColumn(rect);
    Phrase p = createPhrase(String.format("resources/text/liber1_%s_%s.txt", i, la));
    ct.addText(p);
    return ct;
}

在这种情况下,我在文本模式中使用ColumnText,我将不同文件中的文本读入Phrase,如下所示:

public Phrase createPhrase(String path) throws IOException {
    Phrase p = new Phrase();
    BufferedReader in = new BufferedReader(
        new InputStreamReader(new FileInputStream(path), "UTF8"));
    String str;
    while ((str = in.readLine()) != null) {
        p.add(str);
    }
    in.close();
    return p;
}

一旦我定义了ColumnText 对象并添加了它们的内容,我需要将内容呈现到多个页面之一,直到从所有列中呈现所有文本。为此,我们使用这种方法:

public boolean addColumns(ColumnText[] columns) throws DocumentException {
    int status = ColumnText.NO_MORE_TEXT;
    for (ColumnText column : columns) {
        if (ColumnText.hasMoreText(column.go()))
            status = ColumnText.NO_MORE_COLUMN;
    }
    return ColumnText.hasMoreText(status);
}

如您所见,我还会为我开始的每个新部分创建一个新页面。这不是真的必要:我可以将所有部分添加到单个 ColumnText,但取决于拉丁文本如何翻译成英语和法语,您最终可能会出现很大的差异,其中拉丁文本的第 X 部分从一个开始页面和英语或法语的相同部分从另一页开始。因此我选择开始一个新的页面,尽管在这个小的概念证明中它并不是真的必要。

【讨论】:

    猜你喜欢
    • 2016-08-18
    • 2023-03-22
    • 2011-07-10
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多