java使用itextpdf生成 pdf (支持table)分页

先来看一下我做的效果图
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

直接上代码

@Configuration
public class ItextPdfUtils {

    private static final Logger log = LoggerFactory.getLogger(ItextPdfUtils.class);

    private static String SimApiPdfUploadPath;

    private static String SimApiPdfTemplete;

    private static Integer onepagerow;

    private static Integer towpagerow;

    @Value("#{T(java.lang.Integer).parseInt('${pdf_onepagerow:9}')}")
    public void setOnepagerow(Integer onepagerow) {
        ItextPdfUtils.onepagerow = onepagerow;
    }
    @Value("#{T(java.lang.Integer).parseInt('${pdf_towpagerow:22}')}")
    public void setTowpagerow(Integer towpagerow) {
        ItextPdfUtils.towpagerow = towpagerow;
    }

    @Value("${sim_api_pdf_upload_path}")
    public void setSimApiPdfUploadPath(String simApiPdfUploadPath) {
        ItextPdfUtils.SimApiPdfUploadPath = simApiPdfUploadPath;
    }


    @Value("${sim_api_pdf_template}")
    public void setSimApiPdfTemplate(String simApiPdfTemplate) {
        ItextPdfUtils.SimApiPdfTemplete = simApiPdfTemplate;
    }


    // 利用模板生成pdf
    public static File pdfout(ParamVO paramVO, List<OrderPdfVO> orderPdfVOList, String pdfFileName, Integer num) {
        // 模板路径
        String templatePath = SimApiPdfTemplete + File.separator + "sim_shb.pdf";
        // 生成的新文件路径
        String newPDFPath = SimApiPdfUploadPath + File.separator + pdfFileName;
        PdfReader reader;
        FileOutputStream out;
        ByteArrayOutputStream bos;
        PdfStamper stamper;
        try {
            //给表单添加中文字体 这里采用系统字体。不设置的话,中文可能无法显示
            BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
            Font FontChinese = new Font(bf, 5, Font.NORMAL);
            // 输出流
            out = new FileOutputStream(newPDFPath);
            // 读取pdf模板
            reader = new PdfReader(templatePath);
            bos = new ByteArrayOutputStream();
            stamper = new PdfStamper(reader, bos);
            AcroFields form = stamper.getAcroFields();
            Map<String, Object> map = packageMap(paramVO);
            //遍历第一页表单map数据
            Map<String, String> dateheadmap = (Map<String, String>) map.get("dateheadmap");
            // 添加所创建的字体
            form.addSubstitutionFont(bf);
            for (String key : dateheadmap.keySet()) {
                String value = dateheadmap.get(key);
                form.setField(key, value);
            }
            //第一页table数据
            List<AcroFields.FieldPosition> list = form.getFieldPositions("table");
            Rectangle rect = list.get(0).position;
            PdfPTable table = packageTable(rect, orderPdfVOList, 10.0F, num);
            //获取总行数
            int totalRow = table.getRows().size();
            //计算需要分页的总页数
            int totalpage = caculatePageable(totalRow);
            Document document = new Document();
            if (totalpage == 1) {
                //获table页面
                PdfContentByte under = stamper.getOverContent(1);
                //添加table
                table.writeSelectedRows(0, -1, rect.getLeft(), rect.getTop(), under);

            } else {
                //目前模板中暂时解决分页方案 (动态增加空白模板填充值初始化给9个空白模板不包含收尾两个)
                for (int i = 1; i <= totalpage; i++) {
                    document.newPage();
                    PdfContentByte under = stamper.getOverContent(i);
                    if (i == 1) {
                        //第一页显示9+头尾4条
                        table.writeSelectedRows(0, onepagerow, rect.getLeft(), rect.getTop(), under);
                    }
                    //空白模板每页显示22条
                     else {
                        table.writeSelectedRows(onepagerow + towpagerow * (i - 2), onepagerow + towpagerow * (i - 1), 60, 800, under);
                    }
                }
            }

            //遍历最后一页map数据
            Map<String, String> datefootmap = (Map<String, String>) map.get("datefootmap");
            // 添加所创建的字体
            form.addSubstitutionFont(bf);
            for (String key : datefootmap.keySet()) {
                String value = datefootmap.get(key);
                form.setField(key, value);
            }
            // 如果为false,生成的PDF文件可以编辑,如果为true,生成的PDF文件不可以编辑
            stamper.setFormFlattening(true);
            stamper.close();
            Document doc = new Document();
            PdfCopy copy = new PdfCopy(doc, out);
            PdfImportedPage importPage = null;
            doc.open();
            copyvalidPage(totalpage, importPage, reader, copy, bos);
            doc.close();
            File file = new File(newPDFPath);
            return file;
        } catch (IOException e) {
            System.out.print(e);
        } catch (DocumentException e) {
            System.out.print(e);
        }
        return null;
    }


    /**
     *  组装pdf表头表尾的单个域内容
     */
    public static Map packageMap(ParamVO paramVO) {
        //组装pdf表头的单个域内容
        Map<String, String> headmap = new HashMap<String, String>();
        Map<String, String> footmap = new HashMap<String, String>();
        headmap.put("PartnerCode", paramVO.getPartnerCode());
        headmap.put("ReceiverCode", paramVO.getReceiverCode());
        headmap.put("WaybillCustomerName", paramVO.getWaybillCustomerName());
        headmap.put("EndPointName", paramVO.getEndPointName());
        headmap.put("CityName", paramVO.getCityName());
        headmap.put("EndAddress", paramVO.getEndAddress());
        headmap.put("LinkMan", paramVO.getLinkMan());
        headmap.put("ReceiverName", paramVO.getReceiverName());
        headmap.put("Phone", paramVO.getPhone());
        headmap.put("ReceiverPhone", paramVO.getReceiverPhone());
        headmap.put("ShipperCode", paramVO.getShipperCode());
        headmap.put("PoNO", paramVO.getPoNO());
        headmap.put("Route", paramVO.getRoute());
        headmap.put("CustomOrderNO", paramVO.getCustomOrderNO());
        headmap.put("ODBCreateTimeStr", paramVO.getODBCreateTimeStr());
        headmap.put("WaybillNO", paramVO.getWaybillNO());
        headmap.put("EstimateAllNum", paramVO.getEstimateAllNum());
        headmap.put("AllNum", paramVO.getAllNum());
        headmap.put("AllWeight", paramVO.getAllWeight());
        headmap.put("AllVolumn", paramVO.getAllVolumn());
        headmap.put("TotalUnit", paramVO.getTotalUnit());
        if ("1".equals(paramVO.getVirusId())) {
            headmap.put("AllActualNum", paramVO.getAllActualNum());
            headmap.put("AllExceptionNum", paramVO.getAllExceptionNum());
        }
        //尾页
        footmap.put("DCLOgisticts", paramVO.getDCLOgisticts());
        footmap.put("ForwardingAgent", paramVO.getForwardingAgent());
        footmap.put("CustomerNote", paramVO.getCustomerNote());
        footmap.put("WarehouseOperator", paramVO.getWarehouseOperator());
        footmap.put("VehicleNO", paramVO.getVehicleNO());
        footmap.put("TotalActualWeight", paramVO.getTotalActualWeight());
        footmap.put("ContainerNumber", paramVO.getContainerNumber());
        footmap.put("CheckCarOperator", paramVO.getCheckCarOperator());
        if ("1".equals(paramVO.getVirusId())) {
            footmap.put("FreightDate", paramVO.getFreightDate());
            footmap.put("FreightSignature", paramVO.getFreightSignature());
            footmap.put("CustomerDate", formart(new Date()));
            footmap.put("CustomerSignature", paramVO.getUserName());
        }
        if ("0".equals(paramVO.getVirusId())) {
            footmap.put("FreightSignature", paramVO.getUserName());
            footmap.put("FreightDate", formart(new Date()));
        }
        footmap.put("CompanyNote", paramVO.getCompanyNote());
        //组装orderWaybillMap传过去
        Map<String, Object> orderWaybillMap = new HashMap<String, Object>();
        orderWaybillMap.put("dateheadmap", headmap);
        orderWaybillMap.put("datefootmap", footmap);

        return orderWaybillMap;
    }

    /**
     *  组装pdf 中的table 包括样式字体
     */
    public static PdfPTable packageTable(Rectangle rect, List<OrderPdfVO> list, Float fontSize, Integer num) {
        try {
            // 创建table下面通过table.addCell添加的时候必须添加整行内容的所有列
            PdfPTable table = new PdfPTable(num);
            if (num == 8) {
                table.setWidthPercentage(100.0F);
                BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
                //BaseFont bfChinese = BaseFont.createFont("C://Windows//Fonts//simsun.ttc,1" , BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
                Font fontZH = new Font(bfChinese, fontSize == null ? 12F : fontSize, 0);
                //第一行是列表名
                table.setHeaderRows(1);
                table.getDefaultCell().setHorizontalAlignment(1);
                float tatalWidth = rect.getRight() - rect.getLeft() - 1;
                //计算表格宽度
                float[] columnWidth = {(float) (tatalWidth * 0.1),
                        (float) (tatalWidth * 0.2), (float) (tatalWidth * 0.2),
                        (float) (tatalWidth * 0.1), (float) (tatalWidth * 0.1),
                        (float) (tatalWidth * 0.1), (float) (tatalWidth * 0.1),
                        (float) (tatalWidth * 0.1)};
                table.setTotalWidth(columnWidth);
                table.setLockedWidth(true);
                //遍历List 获取每一列的数据,填充到pdfTable中
                list.forEach(orderPdfVO -> {
                    table.addCell(createCell(orderPdfVO.getCol1(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol2(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol3(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol4(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol6(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol7(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol8(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol9(), fontZH));
                });
            }
            if (num == 11) {
                table.setWidthPercentage(100.0F);
                BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
                Font fontZH = new Font(bfChinese, fontSize == null ? 12F : fontSize, 0);
                table.getDefaultCell().setHorizontalAlignment(1);
                float tatalWidth = rect.getRight() - rect.getLeft() - 1;
                //计算表格宽度
                float[] columnWidth = {
                        (float) (tatalWidth * 0.1), (float) (tatalWidth * 0.2),
                        (float) (tatalWidth * 0.1), (float) (tatalWidth * 0.08),
                        (float) (tatalWidth * 0.05), (float) (tatalWidth * 0.08),
                        (float) (tatalWidth * 0.05), (float) (tatalWidth * 0.08),
                        (float) (tatalWidth * 0.08), (float) (tatalWidth * 0.08),
                        (float) (tatalWidth * 0.1)};
                table.setTotalWidth(columnWidth);
                table.setLockedWidth(true);
                //遍历List 获取每一列的数据,填充到pdfTable中
                list.forEach(orderPdfVO -> {
                    table.addCell(createCell(orderPdfVO.getCol1(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol2(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol3(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol4(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol6(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol7(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol8(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol9(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol10(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol11(), fontZH));
                    table.addCell(createCell(orderPdfVO.getCol12(), fontZH));
                });
                //第一行是列表名
                table.setHeaderRows(1);
                //最后3行是表尾总和行
                table.setFooterRows(3);
            }
            //cell跨页
            table.setKeepTogether(true);
            table.setSplitLate(false);
            table.setSplitRows(true);
            return table;
        } catch (Exception e) {
            log.error(e.toString());
            return null;
        }
    }

    /**
     * 创建表格
     * @param value
     * @param fontZH
     * @return
     */
    private static PdfPCell createCell(String value, Font fontZH) {
        PdfPCell cell = new PdfPCell();
        cell.setPhrase(new Phrase(value, fontZH));
        // cell.setBorder(Rectangle.NO_BORDER);
        return cell;
    }

    /**
     * 时间格式转化
     */
    public static String formart(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        date = calendar.getTime();
        String newdate = sdf.format(date);
        return newdate;
    }

    /**
     *  计算分页
     */
    public static int caculatePageable(int totalRow) {
        int totalpage = 1;
        int page = (totalRow - onepagerow) % towpagerow == 0 ? (totalRow - onepagerow) / towpagerow + 1 : (totalRow - onepagerow) / towpagerow + 2;
        return totalRow < onepagerow ? totalpage : page;

    }

    /**
     *  拷贝有效页面
     */
    public static void copyvalidPage(int totalpage, PdfImportedPage importPage, PdfReader reader, PdfCopy copy, ByteArrayOutputStream bos) throws IOException, BadPdfFormatException {
        List<PdfImportedPage> arrayList = new ArrayList();
        for (int i = 1; i <= totalpage; i++) {
            importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), i);
            arrayList.add(importPage);
        }
        //只拷贝有数据的模板包括最后一页固定模板
        importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 11);
        arrayList.add(importPage);
        for (PdfImportedPage newImportPage : arrayList) {
            copy.addPage(newImportPage);
        }
    }

}

方法调用 时传入需要转换的 实体VO

  @Override
    public File simConvertPdf(ParamVO paramVO) {
        //把paramVo 适配成ItextPdf需要的参数类型
        List<OrderPdfVO> list = new ArrayList<>();
        List<Good> goodList = paramVO.getGoodsList();
        //需要创建的模板表格
        Integer num = 0;
        //司机签名模板
        if ("0".equals(paramVO.getVirusId())) {
            if (goodList != null && goodList.size() > 0) {
                //构造表头
                list.add(new OrderPdfVO(
                        "产品编号Materail No",
                        "产品名称和规格/客户产品编码MaterailDescription/CustomerItemCode",
                        "批号/保质期Batch CodeExpiry Date",
                        "批号状态BatchStatus",
                        "数量Quantity",
                        "单位Unit",
                        "毛重  (吨)GrossWeight",
                        "体 积 (m³) Volumn"));
                for (int i = 0; i < goodList.size(); i++) {
                    list.add(new OrderPdfVO(
                            goodList.get(i).getGoodsNO(),
                            goodList.get(i).getGoodsName(),
                            goodList.get(i).getBatchNO(),
                            goodList.get(i).getBatchStatus(),
                            goodList.get(i).getSignNum(),
                            goodList.get(i).getUnit(),
                            goodList.get(i).getSignWeight(),
                            goodList.get(i).getSignVolume()));
                }
                list.add(new OrderPdfVO("","","","总计:",paramVO.getAllNum(),paramVO.getTotalUnit(),paramVO.getAllWeight(),paramVO.getAllVolumn(),"","",""));
                list.add(new OrderPdfVO("","","","","","DSP","","","","",""));
                list.add(new OrderPdfVO("","","","","","EA","","","","",""));

            }
            num = 8;
        }
        //仓管签名模板
        else {
            if (goodList != null && goodList.size() > 0) {
                //构造表头
                list.add(new OrderPdfVO(
                        "产品编号Materail No",
                        "产品名称和规格/客户产品编码MaterailDescription/CustomerItemCode",
                        "批号/保质期Batch CodeExpiry Date",
                        "批号状态BatchStatus",
                        "数量Quantity",
                        "单位Unit",
                        "毛重  (吨)GrossWeight",
                        "体 积 (m³) Volumn",
                        "实收数量 Real Quantity",
                        "异常数量 Abnormal Quantity",
                        "备注 Remark"));
                for (int i = 0; i < goodList.size(); i++) {
                    list.add(new OrderPdfVO(
                                    goodList.get(i).getGoodsNO(),
                                    goodList.get(i).getGoodsName(),
                                    goodList.get(i).getBatchNO(),
                                    goodList.get(i).getBatchStatus(),
                                    goodList.get(i).getSignNum(),
                                    goodList.get(i).getUnit(),
                                    goodList.get(i).getSignWeight(),
                                    goodList.get(i).getSignVolume(),
                                    goodList.get(i).getActualNum(),
                                    goodList.get(i).getExceptionNum()   ,
                                    goodList.get(i).getGoodsRemark()
                            )
                    );
                }
                list.add(new OrderPdfVO("","","","总计:",paramVO.getAllNum(),paramVO.getTotalUnit(),paramVO.getAllWeight(),paramVO.getAllVolumn(),paramVO.getAllActualNum(),paramVO.getAllExceptionNum(),""));
                list.add(new OrderPdfVO("","","","","","DSP","","","","",""));
                list.add(new OrderPdfVO("","","","","","EA","","","","",""));
            }
            num = 11;

        }
        //设置pdf文件名为VirusId +标识雀巢出货单编号
        String pdfName = paramVO.getVirusId()+paramVO.getWaybillNO()+".pdf";
        return ItextPdfUtils.pdfout(paramVO, list, pdfName, num);
    }

每页展示的条数 可在配置文件中配置 具体在我的另一篇博文中找到关于Spring 静态变量注入值

  • 5
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值