关键的思路是:先知道一行可打印的高度h1(比实际小一点),然后表格每添加完一行单元格后,获取表格的高度h2,若h2>h1,那么表格删除最后一行数据table.deleteLastRow(),然后把表格尾部的内容添加到表格,把表格添加进document,然后再新建一页document.newPage(),然后获取剩下需要打印的数据,然后再执行之前的步骤。

关键代码:

            float totalHeight = table.getTotalHeight();

            if (totalHeight > 562.0) {
                table.deleteLastRow();
                setBw(table, pear1, floor, ceil);
                document.add(table);
                document.newPage();
                List<JjjtbmHzbView> jjjtbmHzbViews = allJjjtbmHzbViews.subList(i, allJjjtbmHzbViews.size());
                createHzbTable2(document, btList, jjjtbmHzbViews, gzmbgl, bmrydygl, qj, floor, ceil, pear1, pear2, grape, orange, qr, df);
                return;
            }            

注意:要使table.getTotalHeight()生效,就得table.setTotalWidth(),如果没有设置宽度,那么表格的高度值始终都是0。

源代码注释:the total height of the table. Note that it will be 0 if you didn't specify the width of the table with setTotalWidth(). and made it public

下面是我的实例代码,具体参数看自己业务需求

/**
     *
     * @param document
     * @param btList 表头集合
     * @param views  数据集合
     * @param gzmbgl
     * @param bmrydygl
     * @param qj
     * @param pear1 字体
     * @param pear2 字体
     * @param grape 字体
     * @param orange 字体
     * @param qr 二维码信息
     * @throws IOException
     * @throws WriterException
     * @throws DocumentException
     */
    private void createHzbTable(Document document, List<RslGzmbnrView> btList, List<JjjtbmPdfView> views, Gzmbgl gzmbgl, Bmrydygl bmrydygl, String qj, Font pear1, Font pear2, Font grape, Font orange, String qr) throws IOException, WriterException, DocumentException {
        DecimalFormat df = new DecimalFormat("#,##0.00");
        double floor = Math.floor((double) (btList.size() + 3) / 2);
        double ceil = Math.ceil((double) (btList.size() + 3) / 2);
        List<JjjtbmHzbView> hzbList = getHzbList(btList, views);
        createHzbTable2(document, btList, hzbList, gzmbgl, bmrydygl, qj, floor, ceil, pear1, pear2, grape, orange, qr, df);
    }

    private void createHzbTable2(Document document, List<RslGzmbnrView> btList, List<JjjtbmHzbView> allJjjtbmHzbViews, Gzmbgl gzmbgl, Bmrydygl bmrydygl, String qj, double floor, double ceil, Font pear1, Font pear2, Font grape, Font orange, String qr, DecimalFormat df) throws IOException, WriterException, DocumentException {
        var img = Image.getInstance(qrCodeHelper.write(qr, 60, 60).getAbsolutePath());
        img.setAbsolutePosition(30, PageSize.A4.getWidth() - 70);
        document.add(img);
        var table = new PdfPTable(btList.size() + 3);
        table.setTotalWidth(PageSize.A4.getHeight() - 20f);
        table.setLockedWidth(true);
        table.setHorizontalAlignment(0);
        var dbt = new PdfPCell(new Phrase("【" + gzmbgl.getName() + "】汇总表", grape));
        dbt.setHorizontalAlignment(Element.ALIGN_CENTER);
        dbt.setColspan(btList.size() + 3);
        dbt.setPaddingBottom(25);
        dbt.disableBorderSide(15);
        table.addCell(dbt);

        var bt1 = new PdfPCell(new Phrase("车间名称:" + bmrydygl.getName(), pear1));
        bt1.setHorizontalAlignment(Element.ALIGN_LEFT);
        bt1.setColspan((int) floor);
        bt1.disableBorderSide(15);
        table.addCell(bt1);

        var bt2 = new PdfPCell(new Phrase("日期:" + qj, pear1));
        bt2.setHorizontalAlignment(Element.ALIGN_LEFT);
        bt2.setColspan((int) ceil);
        bt2.disableBorderSide(15);
        table.addCell(bt2);

        addCell(table, "工资类别", pear2, Element.ALIGN_CENTER);

        addCell(table, "部门名称", pear2, Element.ALIGN_CENTER);

        addCell(table, "人数", pear2, Element.ALIGN_CENTER);

        for (var xm : btList) {
            addCell(table, xm.getGzxm(), pear2, Element.ALIGN_CENTER);
        }

        for (int i = 0; i < allJjjtbmHzbViews.size(); i++) {
            addCell(table, allJjjtbmHzbViews.get(i).getGzlb(), orange, Element.ALIGN_CENTER);
            addCell(table, allJjjtbmHzbViews.get(i).getBm(), orange, Element.ALIGN_CENTER);
            addCell(table, allJjjtbmHzbViews.get(i).getRs() + ".00", orange, Element.ALIGN_RIGHT);
            for (var xm : btList) {
                addCell(table, df.format(allJjjtbmHzbViews.get(i).getXms().get(xm.getId())), orange, Element.ALIGN_RIGHT);
            }
            float totalHeight = table.getTotalHeight();
            if (totalHeight > 562.0) {
                table.deleteLastRow();
                setBw(table, pear1, floor, ceil);
                document.add(table);
                document.newPage();
                List<JjjtbmHzbView> jjjtbmHzbViews = allJjjtbmHzbViews.subList(i, allJjjtbmHzbViews.size());
                createHzbTable2(document, btList, jjjtbmHzbViews, gzmbgl, bmrydygl, qj, floor, ceil, pear1, pear2, grape, orange, qr, df);
                return;
            }
        }
        setBw(table, pear1, floor, ceil);
        document.add(table);
    }
private void setBw(PdfPTable table, Font pear1, double floor, double ceil) {
        var bw1 = new PdfPCell(new Phrase("部门负责人:", pear1));
        bw1.setHorizontalAlignment(Element.ALIGN_LEFT);
        bw1.setColspan((int) floor);
        bw1.disableBorderSide(15);
        table.addCell(bw1);

        var bw2 = new PdfPCell(new Phrase("制表人:", pear1));
        bw2.setHorizontalAlignment(Element.ALIGN_LEFT);
        bw2.setColspan((int) ceil);
        bw2.disableBorderSide(15);
        table.addCell(bw2);
    }

 

公司的水印打马赛克,背景水印生成可以看我另一篇文章《JAVA生成PDF文字水印和图片水印》