[更文挑战]iText番盘-PDF神器-12

176 阅读3分钟

「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战

PDF神器iText英文版翻译与学习

作者: 薛大郎.
英文原版:iText in Action 2nd Edition.pdf

坚持. 分享. 成长. 利他 !

一. 前言

上山打(工)虎

1 月 31 日 - 2 月 13 日,每天选取 3 位幸运用户(当天更文时间第一名 + 随机抽取 2 位当天参加更文挑战的用户)

当我看到这个的时候, 掘金果然没令我失望, 礼品很好, 而且 工牌上的文案 也让我很激动, 不知道自己能不能够很幸运, 我的笔名虽然叫薛大郎, 但是我家中排行 老二 , 注定是那个上山打(工)虎的薛二郎, 一定要搞定你这头小脑斧(老虎).

二.正文.

上一篇也已经将在特定位置添加内容讲完了. 主要讲解了pdf中使用了4个层来处理内容, doc.add()添加高级元素是在中间两层, 而 writer.getDirectContent() 和 writer.getDirectContentUnder() 是获取两个处理最上下两层的内容. 然后讲解了PdfContentByte的Api, 然后又讲了XObject的主要两个类, Image和PdfTemplate类. 以及详细介绍了 iText in Action 书中的电影胶卷例子.

6. 使用Table来组织内容

我们这章节将学习创建一个PdfPtable对象, 并介绍PdfPCell类的Api, 然后学习使用Table来将内容加到Document中.

PdfPTable 有三个有参重载构造方法, 非常的实用

// 直接按照relativeWidths数组来配置table列宽比例
public PdfPTable(final float relativeWidths[]) {}
// 根据 列数创建一个列宽比例相同的table
public PdfPTable(final int numColumns) {}
// 根据另一个table常见一个相同的table实例
public PdfPTable(final PdfPTable table) {}

曾经根据需求, 使用Builder模式搞了一个只有下边框为实线的table:

/**
 * 下边框 表格.
 */
public class UnderBorderTable {
    // 实际的table对象
    private final PdfPTable table;
    // 要写入的doc对象
    private final Document doc;
    // builder模式的builder用以最后链式编程的返回, 继续构造
    private final ItextBuilder builder;
    // 下边框表格的构造方法
    public UnderBorderTable(ItextBuilder builder, float[] widths) {
       this.doc = builder.getDoc();
       table = new PdfPTable(widths);
       // 设置为宽度100%的table
       table.setWidthPercentage(100);
       // table中有一个defaultCell的维护 是的不设置时使用默认的cell设置
       table.getDefaultCell().setBorder(Rectangle.NO_BORDER);
       // 设置cell的垂直居中
       table.getDefaultCell().setVerticalAlignment(Element.ALIGN_CENTER);
       // 设置此表之前的间距
       table.setSpacingBefore(8F);
       this.builder = builder;
    }
    // 将table添加到doc中.
   public UnderBorderTable addedTable() throws DocumentException {
       // 可以使用此方法 添加一些默认cell到不完整的最后一行中.
      table.completeRow();
      doc.add(table);
      return this;
   }
   // 获取builder类
   public ItextBuilder getBuilder(){
      return builder;
   }
   // 向table中添加标题, 注意只能添加一次.
   public UnderBorderTable addTitle(String... titles) throws DocumentException {
      for (String cell : titles) {
         PdfPCell pCell = new PdfPCell(new Paragraph(cell, ItextBuilder.DEFAULT_BOLD_FONT));
         pCell.setBorder(Rectangle.BOTTOM);
         // 设置cell的垂直居中
         pCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
         // 设置cell的水平居中
         pCell.setHorizontalAlignment(Element.ALIGN_CENTER);
         table.addCell(pCell);
      }
      return this;
   }
    // 向table中添加内容, 即一行数据.
   public UnderBorderTable addContent(PdfPCell[]... cells) throws DocumentException {
      for (PdfPCell[] cell : cells) {
         for (PdfPCell c : cell) {
            c.setBorder(Rectangle.BOTTOM);
            c.setVerticalAlignment(Element.ALIGN_MIDDLE);
            c.setHorizontalAlignment(Element.ALIGN_CENTER);
            table.addCell(c);
         }
      }
      return this;
   }
}

其实学习table的使用的时候, 可以类比下学习Html中<table> 标签的时候.

    // 新建一个文案的cell
    cell = new PdfPCell(new Phrase("Cell with colspan 3"));
    // 设置占用3列的cell
    cell.setColspan(3);
    table.addCell(cell);
    cell = new PdfPCell(new Phrase("Cell with rowspan 2"));
    // 设置一个跨越2行的cell
    cell.setRowspan(2);
    table.addCell(cell);
    table.addCell("row1;cell1");
    table.addCell("row 1; cell 2");
    table.addCell("row 2; cell 1");
    table.addCell("row 2; cell 2");
 ____________________________________________________
 |_Cell with colspan 3______________________________|
 | Cell with rowspan 2|_row1;cell1___|_row1;cell2___|
 |____________________|_row2;cell1___|_row1;cell2___|

先到这里. 明天继续.