iText - 使用ColumnText进行奇怪的列/页面更改行为

时间:2013-03-13 14:08:34

标签: itext

我是iText的新手并试图完成以下任务:

  • 从本地hd
  • 读取文本文件列表
  • 以2列布局pdf文件排列文件的文本
  • 在每个文本
  • 之前添加连续编号的索引

我从MovieColumns1示例(http://itextpdf.com/examples/iia.php?id=64)开始,最后得到以下代码:

    final float[][] COLUMNS_COORDS = { { 36, 36, 296, 806 }, { 299, 36, 559, 806 } };

    Document document = new Document(PageSize.A4);
    PdfWriter writer = PdfWriter.getInstance(document, resultFile);
    document.open();

    ColumnText ct = new ColumnText(writer.getDirectContent());
    ct.setSimpleColumn(COLUMNS_COORDS[0][0], COLUMNS_COORDS[0][1],
        COLUMNS_COORDS[0][2], COLUMNS_COORDS[0][3]);

    File textDir = new File("c:/Users/raddatz/Desktop/123/texts/");
    File[] files = textDir.listFiles();

    int i = 1;
    int column = 0;
    for (File file : files) {
        String text = FileUtils.readFileToString(file, "UTF-8");
        float yLine = ct.getYLine();
        System.out.println("adding '" + file.getName() + "'");

        PdfPCell theText = new PdfPCell(new Phrase(text, new Font(Font.HELVETICA, 10)));
        theText.setBorder(Rectangle.NO_BORDER);
        theText.setPaddingBottom(10);
        PdfPCell runningNumber = new PdfPCell(new Phrase(new DecimalFormat("00").format(i++), new Font(
            Font.HELVETICA, 14, Font.BOLDITALIC,
            new Color(0.7f, 0.7f, 0.7f))));
        runningNumber.setBorder(Rectangle.NO_BORDER);
        runningNumber.setPaddingBottom(10);
        PdfPTable table = new PdfPTable(2);
        table.setWidths(new int[] { 12, 100 });
        table.addCell(runningNumber);
        table.addCell(theText);
        ct.addElement(table);
        int status = ct.go(true);
        if (ColumnText.hasMoreText(status)) {
            column = Math.abs(column - 1);
            if (column == 0) {
                document.newPage();
                System.out.println("inserting new page with size :" + document.getPageSize());
            }
            ct.setSimpleColumn(
                COLUMNS_COORDS[column][0], COLUMNS_COORDS[column][1],
                COLUMNS_COORDS[column][2], COLUMNS_COORDS[column][3]);
            yLine = COLUMNS_COORDS[column][3];
            System.out.println("correcting yLine to: " + yLine);
        } else {
            ct.addElement(table);
        }
        ct.setYLine(yLine);
        System.out.println("before adding: " + ct.getYLine());
        status = ct.go(false);
        System.out.println("after adding: " + ct.getYLine());
        System.out.println("--------------------------------");
    }

    document.close();

在这里你可以看到结果: http://d.pr/f/NEmx

查看生成的PDF的第一页,我认为一切正常。

但在第二页上你可以看到问题:

  • 文本#31未完全显示(第一行+索引被剪切/不在可见区域中)
  • 文本#46未完全显示(前三行+索引被剪切/不在可见区域中)

在第3页,一切似乎都没问题。我真的迷失在这里。

- 更新(2013-03-14) -

我现在已经分析了PDF的内容。问题不在于内容在非可见区域中显示,而是内容在pdf中根本不存在。内容的缺失部分恰好是适合前一列/页面的部分。所以似乎ColumnText.go(true)正在操纵addElement()之前传递的对象。有人能证实吗?如果是这样的话:我该怎么办呢?

- 结束更新(2013-03-14) -

期待您的回复

的问候, 斯文

1 个答案:

答案 0 :(得分:3)

解决!只要ColumnText指示某个表不适合当前列,我就会使用ColumnText的新实例重新初始化ct并再次添加该表。

换句话说: ColumnText的每个实例都正好处理我的文档的一列。

if (ColumnText.hasMoreText(status) || mediaPoolSwitch) {
  column = Math.abs(column - 1);
  if (mediaPoolSwitch) {
      currentMediaPool = mediapool;
      column = 0;
  }
  if (column == 0) {
      document.newPage();
      writeTitle(writer.getDirectContent(), mediapool.getName());
  }
  ct = new ColumnText(writer.getDirectContent());
  ct.addElement(table);
  ct.setSimpleColumn(
      COLUMNS_COORDS[column][0], COLUMNS_COORDS[column][1],
      COLUMNS_COORDS[column][2], COLUMNS_COORDS[column][3]);
  yLine = COLUMNS_COORDS[column][3];
  LOG.debug("correcting yLine to: " + yLine);
} else {
  ct.addElement(table);
}
ct.setYLine(yLine);
ct.go();