将页面分成两部分,这样我们就可以用不同的来源填充每个部分
Divide page in 2 parts so we can fill each with different source
我需要创建一个用户指南,我必须将内容以 2 种不同的语言放在同一页面上。所以页面的前半部分是英文,而后半部分是法文。 (将来他们可能还会要求第三种语言,但最多 3 种)。所以每个页面都会有 2 个块。如何在 java 中使用 iTextPDF 实现此目的?
更新
为了更深入地了解问题,以下是结构。
如果我正确理解你的问题,你需要创建这样的东西:
在此屏幕截图中,您可以看到凯撒对高卢人的评论第一本书的第一部分 War。 Gallia omnia est divisa in partes tres, 本文档的每一页也是如此:上半部分显示拉丁文文本,中间部分显示英文文本,下半部分显示法语文本。如果你读过这篇文章,你会发现像我这样的比利时人被认为是最勇敢的(尽管我们并不像人们希望的那样文明)。如果您想查看 PDF,请参阅 three_parts.pdf。
此 PDF 是使用 ThreeParts 示例创建的。在这个例子中,我有 9 个文本文件:
- http://itextpdf.com/sites/default/files/liber1_1_la.txt
- http://itextpdf.com/sites/default/files/liber1_1_en.txt
- http://itextpdf.com/sites/default/files/liber1_1_fr.txt
- http://itextpdf.com/sites/default/files/liber1_2_la.txt
- http://itextpdf.com/sites/default/files/liber1_2_en.txt
- http://itextpdf.com/sites/default/files/liber1_2_fr.txt
- http://itextpdf.com/sites/default/files/liber1_3_la.txt
- http://itextpdf.com/sites/default/files/liber1_3_en.txt
- http://itextpdf.com/sites/default/files/liber1_3_fr.txt
Liber 在拉丁语中是书的意思,因此所有文件都是第一本书的片段,更具体地说是第 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 部分开始处出现很大的差异在一页上,英文或法文的同一部分在另一页开始。因此我选择开始一个新页面,尽管在这个小小的概念证明中并不是真的有必要。
我需要创建一个用户指南,我必须将内容以 2 种不同的语言放在同一页面上。所以页面的前半部分是英文,而后半部分是法文。 (将来他们可能还会要求第三种语言,但最多 3 种)。所以每个页面都会有 2 个块。如何在 java 中使用 iTextPDF 实现此目的?
更新
为了更深入地了解问题,以下是结构。
如果我正确理解你的问题,你需要创建这样的东西:
在此屏幕截图中,您可以看到凯撒对高卢人的评论第一本书的第一部分 War。 Gallia omnia est divisa in partes tres, 本文档的每一页也是如此:上半部分显示拉丁文文本,中间部分显示英文文本,下半部分显示法语文本。如果你读过这篇文章,你会发现像我这样的比利时人被认为是最勇敢的(尽管我们并不像人们希望的那样文明)。如果您想查看 PDF,请参阅 three_parts.pdf。
此 PDF 是使用 ThreeParts 示例创建的。在这个例子中,我有 9 个文本文件:
- http://itextpdf.com/sites/default/files/liber1_1_la.txt
- http://itextpdf.com/sites/default/files/liber1_1_en.txt
- http://itextpdf.com/sites/default/files/liber1_1_fr.txt
- http://itextpdf.com/sites/default/files/liber1_2_la.txt
- http://itextpdf.com/sites/default/files/liber1_2_en.txt
- http://itextpdf.com/sites/default/files/liber1_2_fr.txt
- http://itextpdf.com/sites/default/files/liber1_3_la.txt
- http://itextpdf.com/sites/default/files/liber1_3_en.txt
- http://itextpdf.com/sites/default/files/liber1_3_fr.txt
Liber 在拉丁语中是书的意思,因此所有文件都是第一本书的片段,更具体地说是第 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 部分开始处出现很大的差异在一页上,英文或法文的同一部分在另一页开始。因此我选择开始一个新页面,尽管在这个小小的概念证明中并不是真的有必要。