itext7でPDFを作成する～自由配置：表～

#表を自由配置しよう
今回は表を自由配置。
前回のParagraphでは位置が微妙にずれてしまっていたので、セル1つの表などにして文字列を配置するのもひとつの手と考える。

#早速コード

```FreePosTable.java
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.ColumnDocumentRenderer;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.borders.Border;
import com.itextpdf.layout.borders.SolidBorder;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.HorizontalAlignment;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.UnitValue;

public class FreePosTable {
    public static void main(String[] args) throws Exception {
        PdfDocument pdf = new PdfDocument(new PdfWriter("FreePosTable.pdf"));
        PageSize ps = PageSize.A4.rotate();
        PdfPage page = pdf.addNewPage(ps);
        PdfCanvas canvas = new PdfCanvas(page);

        
        // 平成角ゴシック
        PdfFont font = PdfFontFactory.createFont("HeiseiKakuGo-W5", "UniJIS-UCS2-H");
 

        // Initialize document
        Document document = new Document(pdf);
 
        // (100, 200)にwidth:50, height:100を指定
        Rectangle[] columns = {
                new Rectangle(100, 200, 400, 100), // x,y,width,height
        };
        document.setRenderer(new ColumnDocumentRenderer(document, columns));

        // テーブル定義：3列を幅の割合を100:200:300に指定
        Table table = new Table(new float[]{100,200,300});
        table.setWidth(UnitValue.createPercentValue(100))
                .setTextAlignment(TextAlignment.CENTER)
                .setHorizontalAlignment(HorizontalAlignment.CENTER);

        // テーブルのヘッダ指定
        Cell cell = new Cell();
        cell.add(new Paragraph("ヘッダ1"));
        table.addCell(cell);
        Cell cell2 = new Cell();
        cell2.add(new Paragraph("ヘッダ2"));
        table.addCell(cell2);
        Cell cell3 = new Cell();
        cell3.add(new Paragraph("ヘッダ3"));
        table.addCell(cell3);

        // テーブルのボディ部を3行指定
        for (int x = 0; x < 3; x++) {
            for (int y = 0; y < 3; y++) {
                table.addCell("セル" + x + "-" + y);
            }
        }

        // テーブルのフッタ指定
        table.addFooterCell("フッタ1");
        table.addFooterCell("フッタ2");
        table.addFooterCell("フッタ3");

        // テーブルの枠等を指定
        Border border = new SolidBorder(ColorConstants.RED, 1.5f);
        table.setFont(font);
        table.setBorder(border);
        document.add(table);

        // (100, 200)へ線。width:400, height:100の範囲をチェック
        // また上部は100ごとに線を入れておく
        canvas.moveTo(0, 0).lineTo(100, 200).lineTo(500, 200)
        .lineTo(500, 310).moveTo(500, 300)
        .lineTo(400, 300).lineTo(400, 310).moveTo(400, 300)
        .lineTo(300, 300).lineTo(300, 310).moveTo(300, 300)
        .lineTo(200, 300).lineTo(200, 310).moveTo(200, 300)
        .lineTo(100, 300).lineTo(100, 310).moveTo(100, 300)
        .stroke();

        //Close document
        document.close();
    }
}
```

#説明
位置の指定は前回と同じ。
幅をわかりやすくするため、100毎にきざみをつけてみた。

出力イメージ
<img width="552" alt="FreePosTable.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/322537/ace1d619-50b6-bea9-9c16-3d3d9e0a5e8d.jpeg">


#書き出しは指定位置＋指定高さ。
表も文字列同様に指定位置から高さ分上から表示される。
表ではずれがないようだ。

#はみ出した分は次ページの同位置に出力される
やはりはみ出した行は次のページに表示される。
ただ、ヘッダフッタは各ページに表示されるようだ。

#列の幅指定
Table table = new Table(new float[]{100,200,300});で3列の指定であること、それぞれの幅の割合が100:200:300であることを表している。
指定幅は400だがこれとは関係なく割合で幅が設定される。
ただ、new float[]{1,2,3}ではなぜか等幅となってしまった(旧バージョンはできていたような？)また、new float[]{10,20,30}ではエラーとなってしまった。なんでだろ。
とりあえずは、ある程度大きい値で指定すればよいと思われる。、