关键的思路是:先知道一行可打印的高度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文字水印和图片水印》。