itext5动态创建表格

依赖基于:PDF模板填充,基于IText5-CSDN博客

工具类

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * PDF动态表格(基于itext5)
 */
public class PDFDynamicTable {

    private transient final Document document;

    /**
     * 字体,默认:STSong-Light
     */
    private BaseFont baseFont;

    /**
     * 表头
     */
    private List<CellData[]> headers;

    public static PDFDynamicTable load() throws DocumentException, IOException {
        return new PDFDynamicTable();
    }

    /**
     * 设置表格边距
     *
     * @param marginLR - 左右边距
     * @param marginTB - 上下边距
     */
    public PDFDynamicTable margin(float marginLR, float marginTB) {
        marginLR = Math.max(this.document.leftMargin(), marginLR);
        marginTB = Math.max(this.document.topMargin(), marginTB);
        this.document.setMargins(marginLR, marginLR, marginTB, marginTB);
        return this;
    }

    /**
     * 添加表头
     */
    public PDFDynamicTable headers(List<CellData[]> headers) {
        if (headers == null) {
            return this;
        }
        this.headers = headers;
        return this;
    }

    public byte[] create(List<CellData[]> tableData) throws DocumentException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        PdfWriter writer = PdfWriter.getInstance(document, out);
        // 打开文档
        document.open();
        // 创建动态表格
        document.add(doCreateDynamicTable(tableData));
        document.close();
        writer.close();
        return out.toByteArray();
    }

    private PdfPTable doCreateDynamicTable(List<CellData[]> tableData) {
        Rectangle rectangle = document.getPageSize();
        PdfPTable table = new PdfPTable(tableData.get(0).length);
        table.setExtendLastRow(false);
        table.setLockedWidth(true);
        float totalWidth = rectangle.getWidth() - document.leftMargin() - document.rightMargin();
        table.setTotalWidth(totalWidth);
        // 添加表头
        if (!this.headers.isEmpty()) {
            table.setHeaderRows(this.headers.size());
            handleTableCellData(table, headers);
        }
        // 添加表体
        handleTableCellData(table, tableData);
        return table;
    }

    private void handleTableCellData(PdfPTable table, List<CellData[]> dataList) {
        out:
        for (CellData[] dataArray : dataList) {
            for (int j = 0; j < dataArray.length; j++) {
                CellData data = dataArray[j];
                if (data == null) {
                    // 结束当前行
                    table.completeRow();
                    continue out;
                }
                PdfPCell cell = createPdfCell(data.value, data.fontSize, data.hAlign, data.vAlign);
                // 合并列
                int colspan = Math.min(dataArray.length - j, data.colspan);
                cell.setColspan(colspan);
                table.addCell(cell);
                if (colspan == dataArray.length) {
                    // 结束当前行
                    table.completeRow();
                    continue out;
                }
            }
        }
    }

    private PDFDynamicTable() throws DocumentException, IOException {
        this.document = new Document();
        this.baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        this.headers = Collections.emptyList();
    }

    private PdfPCell createPdfCell(String content, float fontSize, int hAlign, int vAlign) {
        PdfPCell cell = new PdfPCell();
        cell.setBorder(Rectangle.BOX);
        cell.setBorderWidth(0.5F);
        cell.setPadding(5F);
        cell.setHorizontalAlignment(hAlign);
        cell.setVerticalAlignment(vAlign);
        cell.setPhrase(createContent(content, fontSize));
        return cell;
    }

    private Phrase createContent(String content, float fontSize) {
        Phrase phrase = new Phrase();
        phrase.setFont(new Font(baseFont, fontSize));
        phrase.add(content);
        return phrase;
    }


    public static class CellData {
        /**
         * 标题内容
         */
        private String value;

        /**
         * 当前单元格合并列数(默认为0,不合并)
         */
        private int colspan;

        /**
         * 字体大小
         */
        private float fontSize;

        /**
         * 水平对齐方式
         * <p>
         * 0-LEFT;
         * 1-CENTER;
         * 2-RIGHT
         */
        private int hAlign;

        /**
         * 垂直对齐方式
         * <p>
         * 4-TOP;
         * 5-MIDDLE;
         * 6-BOTTOM
         */
        private int vAlign;

        public CellData(String value) {
            this(value, 10.5F);
        }

        public CellData(String value, float fontSize) {
            this(value, 1, fontSize);
        }

        public CellData(String value, int colspan, float fontSize) {
            this(value, Math.max(1, colspan), fontSize, Element.ALIGN_LEFT, Element.ALIGN_MIDDLE);
        }

        public CellData(String value, int colspan, float fontSize, int hAlign) {
            this(value, colspan, fontSize, hAlign, Element.ALIGN_MIDDLE);
        }

        public CellData(String value, int colspan, float fontSize, int hAlign, int vAlign) {
            this.value = value;
            this.colspan = Math.max(1, colspan);
            this.fontSize = fontSize;
            this.hAlign = Arrays.asList(0, 1, 2).contains(hAlign) ? hAlign : Element.ALIGN_LEFT;
            this.vAlign = Arrays.asList(4, 5, 6).contains(vAlign) ? vAlign : Element.ALIGN_MIDDLE;
        }
    }
}

测试demo

public static void main(String[] args) throws DocumentException, IOException {
        String dir = FileSystemView.getFileSystemView().getHomeDirectory().getPath() + "/table/";
        List<PDFDynamicTable.CellData[]> headers = new ArrayList<>();
        PDFDynamicTable.CellData[] head = new PDFDynamicTable.CellData[2];
        head[0] = new PDFDynamicTable.CellData("测试标题数据", 2, 20F, Element.ALIGN_CENTER);
        headers.add(head);

        PDFDynamicTable.CellData[] head1 = new PDFDynamicTable.CellData[2];
        head1[0] = new PDFDynamicTable.CellData("第一列标题");
        head1[1] = new PDFDynamicTable.CellData("第二列标题");
        headers.add(head1);
        List<PDFDynamicTable.CellData[]> data = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            PDFDynamicTable.CellData[] arr = new PDFDynamicTable.CellData[2];
            arr[0] = new PDFDynamicTable.CellData("row " + (i + 1) + ", col 1");
            arr[1] = new PDFDynamicTable.CellData("row " + (i + 1) + ", col 2");
            data.add(arr);
        }
        byte[] bytes = PDFDynamicTable.load()
                .margin(120F, 50F)
                .headers(headers)
                .create(data);
        IOUtils.write(bytes, Files.newOutputStream(Paths.get(dir + System.nanoTime() + ".pdf")));
    }

  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流沙QS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值