Java使用itext生成复杂数据的pdf的示例代码

 更新时间:2024年12月15日 10:49:19   作者:Java小王子呀  
Apache iText 是一个开源 Java 库,支持 PDF 文档的开发和转换,在本教程中,我们将学习如何使用 iText 开发可以创建、转换和操作 PDF 文档的 Java 程序,感兴趣的小伙伴跟着小编一起来看看吧

首先,什么是Itext

Apache iText 是一个开源 Java 库,支持 PDF 文档的开发和转换。
在本教程中,我们将学习如何使用 iText 开发可以创建、转换和操作 PDF 文档的 Java 程序。
Itext目前遵从AGPL开源协议,AGPL 可以说是最严格的 GPL 了,强传染性,即使是 RPC 调用也会被感染,不发行软件而是作为 web 服务对外提供也必须开放源代码
目前Itext有很多product开始收费,但你所需的功能基本上open source都能满足

特点:

以下是 iText 库的显着特点 −

  • Interactive − iText 为你提供类(API)来生成交互式 PDF 文档。使用这些,你可以创建地图和书籍。
  • Adding bookmarks, page numbers, etc − 使用 iText,你可以添加书签、页码和水印。
  • Split & Merge − 使用 iText,你可以将现有的 PDF 拆分为多个 PDF,还可以向其中添加/连接其他页面。
  • Fill Forms − 使用 iText,你可以在 PDF 文档中填写交互式表单。
  • Save as Image − 使用 iText,你可以将 PDF 保存为图像文件,例如 PNG 或 JPEG。
  • Canvas − iText 库为您提供了一个 Canvas 类,你可以使用它在 PDF 文档上绘制各种几何形状,如圆形、线条等。
  • Create PDFs − 使用 iText,你可以从 Java 程序创建新的 PDF 文件。你也可以包含图像和字体。
  • 下载地址:Examples

    iText官网: The Leading PDF Library for Developers | iText

一 上依赖

            <!-- ITEXTPDF 依赖 -->
            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itextpdf</artifactId>
                <version>${com.itextpdf.version}</version>
            </dependency>
 
<com.itextpdf.version>5.5.13.2</com.itextpdf.version>

二 ctroller层

HttpServletResponse:用于将生成的 PDF 文件直接写入 HTTP 响应流中,以便客户端可以下载或查看 PDF 文件。

目前,方法声明抛出了 Exception,这会导致所有未捕获的异常都被抛出到客户端。为了提高代码的健壮性,建议捕获特定的异常,并根据不同的异常类型返回适当的 HTTP 状态码和错误信息。

例如,你可以使用 @ExceptionHandler 来捕获常见的异常,如 IOExceptionDocumentException 等,并返回 500 Internal Server Error 或其他适当的响应。

    @PostMapping(value = "print/sorting", produces = MediaType.APPLICATION_PDF_VALUE)
    @ApiOperation(value = "打印分拣清单(新)", produces = MediaType.APPLICATION_PDF_VALUE)
    public void printSortingNew(@Valid @RequestBody SortingPrintRequest request, HttpServletResponse response){
        crossdockSortingService.printSortingNew(request,response);
    }

三  Service层

按照业务逻辑从数据库获取数据并处理数据,放到合适的对象里

(这里主要是和业务相关,不必深究里面内容,最后能得出需要的数据传出即可)

@Override
    public void printSorting(SortingPrintRequest request, HttpServletResponse response) throws IOException {
        Crossdock crossdock1 = crossdockService.getByFieldValue(request.getOrderNo(), Crossdock::getOrderNo);
        Set<String> idSet = Sets.newHashSet();idSet.add(crossdock1.getId());
        // 集装箱编号/柜号、柜型
            List<Crossdock> crossdockList = crossdockService.listByFieldValueSet(idSet, Crossdock::getId);
            if (ObjectUtils.isEmpty(crossdockList)) {
                throw new ApiException(ResultCode.PARAMES_INVALID);
            }
            // 统计快递、卡派、自提、存仓数量
            List<CrossdockPlan> crossdockPlanByOrderList = crossdockPlanService.listByFieldValueSet(idSet, CrossdockPlan::getOrderId);
            Map<String, List<CrossdockPlan>> crossdockPlanOrderIdMap = crossdockPlanByOrderList.stream().collect(Collectors.groupingBy(CrossdockPlan::getOrderId));
            // 客户id、公司
            // 客户(发件人)信息 customerVo
            Set<String> customerIdSet = crossdockList.stream().map(Crossdock::getCustomerId).collect(Collectors.toSet());
            Map<String, Customer> customerMap = customerService.mapByFieldValueSet(customerIdSet, Customer::getId);
            // 箱数统计,分拣表
            List<CrossdockSorting> crossdockSortingList = listByFieldValueSet(idSet, CrossdockSorting::getOrderId);
            Map<String, List<CrossdockSorting>> crossdockSortingMap = crossdockSortingList.stream().collect(Collectors.groupingBy(CrossdockSorting::getOrderId));
            Set<String> sortingIdSet = crossdockSortingList.stream().map(CrossdockSorting::getId).collect(Collectors.toSet());
            List<CrossdockSortingItem> crossdockSortingItemList = crossdockSortingItemService.listByFieldValueSet(sortingIdSet, CrossdockSortingItem::getSortingId);
            Map<String, List<CrossdockSortingItem>> crossdockSortingItemMap = crossdockSortingItemList.stream().collect(Collectors.groupingBy(CrossdockSortingItem::getSortingId));
            // 公司信息
            Set<String> companySet = crossdockList.stream().map(Crossdock::getCompanyId).collect(Collectors.toSet());
            Map<String, Company> companyMap = companyService.mapByFieldValueSet(companySet, Company::getId);
            // 拼接参数
            List<ExportSortingVo> exportSortingVoList = new ArrayList<>();
            Map<String, List<ExportSortingDetailVo>> exportSortingDetailVoMap = new HashMap<>(16);
            for (Crossdock crossdock : crossdockList) {
                ExportSortingVo exportSortingVo = new ExportSortingVo();
                exportSortingVo.setKey(crossdock.getOrderNo());
                exportSortingVo.setCabinetType(crossdock.getContainerType());
                exportSortingVo.setCtnr(crossdock.getContainerNo());
                exportSortingVo.setCompany(companyMap.containsKey(crossdock.getCompanyId()) ? companyMap.get(crossdock.getCompanyId()).getName() : null);
                if (customerMap.containsKey(crossdock.getCustomerId())) {
                    exportSortingVo.setCustomerCode(customerMap.get(crossdock.getCustomerId()).getCode());
                }
                // 设置统计数量
                if (crossdockPlanOrderIdMap.containsKey(crossdock.getId())) {
                    List<CrossdockPlan> crossdockPlanList = crossdockPlanOrderIdMap.get(crossdock.getId());
                    // 快递
                    Map<String, List<CrossdockPlan>> shippingTypeMap = crossdockPlanList.stream().collect(Collectors.groupingBy(CrossdockPlan::getShippingType));
                    if (shippingTypeMap.containsKey(CrossdockEnums.ShippingType.EXPRESS.name())) {
                        List<CrossdockPlan> expressCrossdockPlanList = shippingTypeMap.get(CrossdockEnums.ShippingType.EXPRESS.name());
                        BigDecimal expressAmount = expressCrossdockPlanList.stream().filter(crossdockPlan -> !ObjectUtils.isEmpty(crossdockPlan.getTotalAmount()))
                                .map(CrossdockPlan::getTotalAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                        exportSortingVo.setUps(expressAmount);
                    }
                    // 卡车
                    if (shippingTypeMap.containsKey(CrossdockEnums.ShippingType.TRUCK.name())) {
                        List<CrossdockPlan> truckCrossdockPlanList = shippingTypeMap.get(CrossdockEnums.ShippingType.TRUCK.name());
                        BigDecimal truckAmount = truckCrossdockPlanList.stream().filter(crossdockPlan -> !ObjectUtils.isEmpty(crossdockPlan.getTotalAmount()))
                                .map(CrossdockPlan::getTotalAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                        exportSortingVo.setTruck(truckAmount);
                    }
                    // 自提
                    if (shippingTypeMap.containsKey(CrossdockEnums.ShippingType.SELF.name())) {
                        List<CrossdockPlan> selfCrossdockPlanList = shippingTypeMap.get(CrossdockEnums.ShippingType.SELF.name());
                        BigDecimal selfAmount = selfCrossdockPlanList.stream().filter(crossdockPlan -> !ObjectUtils.isEmpty(crossdockPlan.getTotalAmount()))
                                .map(CrossdockPlan::getTotalAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                        exportSortingVo.setSelf(selfAmount);
                    }
                    // 总数
                    BigDecimal totalAmount = crossdockPlanList.stream().filter(crossdockPlan -> !ObjectUtils.isEmpty(crossdockPlan.getTotalAmount()))
                            .map(CrossdockPlan::getTotalAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                    exportSortingVo.setTotal(crossdock.getTotalAmount());       //这里设置的总箱数应该是转运单里面的总箱数
                    // 留仓/hold
                    BigDecimal warehouseAmount = crossdock.getTotalAmount().subtract(totalAmount);
                    exportSortingVo.setWarehouse(warehouseAmount);
                }
                exportSortingVoList.add(exportSortingVo);
                // 设置分拣详细信息
                List<ExportSortingDetailVo> exportSortingDetailVoList = new ArrayList<>();
                if (crossdockSortingMap.containsKey(crossdock.getId())) {
                    List<CrossdockSorting> crossdockSortingByOrderIdList = crossdockSortingMap.get(crossdock.getId());
                    for (CrossdockSorting crossdockSorting : crossdockSortingByOrderIdList) {
                        if (crossdockSortingItemMap.containsKey(crossdockSorting.getId())) {
                            CrossdockPlan plan = crossdockPlanService.getByFieldValue(crossdockSorting.getSortingPlanRid(), CrossdockPlan::getSortingPlanRid);
                            List<CrossdockPlanGoods> planGoodsList = null;
                            if (plan != null) {
                                planGoodsList = crossdockPlanGoodsService.list(new QueryWrapper<CrossdockPlanGoods>().lambda()
                                        .eq(CrossdockPlanGoods::getPlanId, plan.getId()));
                            }
                            // 箱子信息
                            List<CrossdockSortingItem> crossdockSortingItems = crossdockSortingItemMap.get(crossdockSorting.getId());
                            for (CrossdockSortingItem crossdockSortingItem : crossdockSortingItems) {
                                ExportSortingDetailVo exportSortingDetailVo = new ExportSortingDetailVo();
                                exportSortingDetailVo.setInstructions(crossdockSortingItem.getNote());
                                exportSortingDetailVo.setOrderNo(crossdockSortingItem.getPlNo());
                                exportSortingDetailVo.setBoxesNo(crossdockSortingItem.getPackageNum());
 
                                exportSortingDetailVo.setCbm(BigDecimal.ZERO);
                                if (CollectionUtils.isNotEmpty(planGoodsList)){
                                    List<CrossdockPlanGoods> filterPlanGoodsList = planGoodsList.stream()
                                            .filter(Objects::nonNull)
                                            .filter(x -> Objects.equals(x.getFbaNumber(), crossdockSortingItem.getPlNo()))
                                            .collect(Collectors.toList());
                                    exportSortingDetailVo.setCbm(CollectionUtils.isNotEmpty(filterPlanGoodsList) ? filterPlanGoodsList.get(0).getCbm() : BigDecimal.ZERO);
                                }
 
                                exportSortingDetailVo.setPalletsNo(crossdockSorting.getInboundPallet());
                                exportSortingDetailVo.setStorageLocation(null);
                                exportSortingDetailVo.setSubtotalQuantity(crossdockSorting.getPackageNum());
 
                                if (plan != null && plan.getIsHold()) {
                                    exportSortingDetailVo.setWarehouseCode(crossdockSorting.getSortingNote() + "-HOLD");
                                } else {
                                    exportSortingDetailVo.setWarehouseCode(crossdockSorting.getSortingNote());
                                }
                                exportSortingDetailVoList.add(exportSortingDetailVo);
                            }
                            exportSortingDetailVoMap.put(crossdock.getOrderNo(), exportSortingDetailVoList);
                        }
                    }
                }
            }
            complexFill(exportSortingVoList, exportSortingDetailVoMap, response);
    }

上面数据处理好放进去然后继续调用

 public void complexFill(List<ExportSortingVo> baseInfoList, Map<String, List<ExportSortingDetailVo>> detailInfoMap, HttpServletResponse response) throws IOException {
        byte[] pdfBytes = convertExcelToPdf(baseInfoList,detailInfoMap);
        // 设置响应头
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "attachment; filename="+detailInfoMap.keySet().iterator().next()+".pdf");
        // 获取响应输出流
        OutputStream outputStream = response.getOutputStream();
        outputStream.write(pdfBytes);
        outputStream.flush();
        outputStream.close();
        //打印日志
        PrintLogCreateRequest request = new PrintLogCreateRequest();
        request.setPrintNo(detailInfoMap.keySet().iterator().next());
        request.setPrintType(PrintEnums.type.SORTING.name());
        printLogService.createPrintLog(request);
    }
  • 捕获特定异常:目前,方法声明抛出了 IOException,但没有处理其他可能的异常(如 NullPointerException 或 IllegalArgumentException)。建议捕获特定的异常,并根据不同的异常类型返回适当的错误信息。

private byte[] convertExcelToPdf(List<ExportSortingVo> baseInfoList,Map<String, List<ExportSortingDetailVo>> detailInfoMap) throws IOException{
        Document document = new Document();
        ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();
        try {
            PdfWriter writer = PdfWriter.getInstance(document, pdfOutputStream);
            BaseFont bf = BaseFont.createFont(TEMPLATE_FONT, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            // 设置页边距
            document.setMargins(1, 1, 10, 10);
            document.open();
            ExportSortingVo sorting = baseInfoList.get(0);
            PdfPTable table = new PdfPTable(8); // 有8列
            // 第一行
            PdfPCell cell1 = new PdfPCell(new Paragraph("客户编号:"+sorting.getCustomerCode(),new Font(bf,12,Font.NORMAL)));
            cell1.setColspan(1);
            cell1.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell1);
            PdfPCell cell2 = new PdfPCell(new Paragraph("总数",new Font(bf,12,Font.NORMAL)));
            cell2.setColspan(1);
            cell2.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell2);
            PdfPCell cell3 = new PdfPCell(new Paragraph(" ",new Font(bf,12,Font.NORMAL)));
            cell3.setColspan(1);
            cell3.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell3);
            PdfPCell cell4 = new PdfPCell(new Paragraph(ObjectUtils.isEmpty(sorting.getTotal()) ? StringUtils.EMPTY : sorting.getTotal().stripTrailingZeros().toPlainString(),new Font(bf,12,Font.NORMAL)));
            cell4.setColspan(3);
            cell4.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell4);
            PdfPCell cell5 = new PdfPCell(new Paragraph("拆柜公司",new Font(bf,12,Font.NORMAL)));
            cell5.setColspan(1);
            cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell5);
            PdfPCell cell6 = new PdfPCell(new Paragraph(" ",new Font(bf,12,Font.NORMAL)));
            cell6.setColspan(1);
            cell6.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell6);
            // 第二行
            PdfPCell cell7 = new PdfPCell(new Paragraph("公司:"+sorting.getCompany(),new Font(bf,12,Font.NORMAL)));
            cell7.setColspan(1);
            cell7.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell7);
            PdfPCell cell8 = new PdfPCell(new Paragraph("UPS/Fedex",new Font(bf,12,Font.NORMAL)));
            cell8.setColspan(1);
            cell8.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell8);
            PdfPCell cell9 = new PdfPCell(new Paragraph(" ", new Font(bf, 12, Font.NORMAL)));
            cell9.setColspan(1);
            cell9.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell9);
            PdfPCell cell10 = new PdfPCell(new Paragraph(ObjectUtils.isEmpty(sorting.getUps()) ? StringUtils.EMPTY : sorting.getUps().stripTrailingZeros().toPlainString(), new Font(bf, 12, Font.NORMAL)));
            cell10.setColspan(3);
            cell10.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell10);
            PdfPCell cell11 = new PdfPCell(new Paragraph("拆柜码头", new Font(bf, 12, Font.NORMAL)));
            cell11.setColspan(1);
            cell11.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell11);
            PdfPCell cell12 = new PdfPCell(new Paragraph(" ", new Font(bf, 12, Font.NORMAL)));
            cell12.setColspan(1);
            cell12.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell12);
            // 第三行
            PdfPCell cell13 = new PdfPCell(new Paragraph("柜号:"+sorting.getCtnr(),new Font(bf,12,Font.NORMAL)));
            cell13.setColspan(1);
            cell13.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell13);
            PdfPCell cell14 = new PdfPCell(new Paragraph("留仓/Hold",new Font(bf,12,Font.NORMAL)));
            cell14.setColspan(1);
            cell14.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell14);
            PdfPCell cell15 = new PdfPCell(new Paragraph(" ", new Font(bf, 12, Font.NORMAL)));
            cell15.setColspan(1);
            cell15.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell15);
            PdfPCell cell16 = new PdfPCell(new Paragraph(ObjectUtils.isEmpty(sorting.getWarehouse()) ? StringUtils.EMPTY : sorting.getWarehouse().stripTrailingZeros().toPlainString(), new Font(bf, 12, Font.NORMAL)));
            cell16.setColspan(3);
            cell16.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell16);
            PdfPCell cell17 = new PdfPCell(new Paragraph("拆柜开始时间", new Font(bf, 12, Font.NORMAL)));
            cell17.setColspan(1);
            cell17.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell17);
            PdfPCell cell18 = new PdfPCell(new Paragraph(" ", new Font(bf, 12, Font.NORMAL)));
            cell18.setColspan(1);
            cell18.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell18);
            // 第四行
            PdfPCell cell19 = new PdfPCell(new Paragraph("柜式:"+sorting.getCabinetType(),new Font(bf,12,Font.NORMAL)));
            cell19.setColspan(1);
            cell19.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell19);
            PdfPCell cell20 = new PdfPCell(new Paragraph("卡派",new Font(bf,12,Font.NORMAL)));
            cell20.setColspan(1);
            cell20.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell20);
            PdfPCell cell21 = new PdfPCell(new Paragraph(" ", new Font(bf, 12, Font.NORMAL)));
            cell21.setColspan(1);
            cell21.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell21);
            PdfPCell cell22 = new PdfPCell(new Paragraph(ObjectUtils.isEmpty(sorting.getTruck()) ? StringUtils.EMPTY : sorting.getTruck().stripTrailingZeros().toPlainString(), new Font(bf, 12, Font.NORMAL)));
            cell22.setColspan(3);
            cell22.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell22);
            PdfPCell cell23 = new PdfPCell(new Paragraph("拆柜结束时间", new Font(bf, 12, Font.NORMAL)));
            cell23.setColspan(1);
            cell23.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell23);
            PdfPCell cell24 = new PdfPCell(new Paragraph(" ", new Font(bf, 12, Font.NORMAL)));
            cell24.setColspan(1);
            cell24.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell24);
            // 第五行
            PdfPCell cell25 = new PdfPCell(new Paragraph(" ",new Font(bf,12,Font.NORMAL)));
            cell25.setColspan(1);
            cell25.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell25);
            PdfPCell cell26 = new PdfPCell(new Paragraph("自提",new Font(bf,12,Font.NORMAL)));
            cell26.setColspan(1);
            cell26.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell26);
            PdfPCell cell27 = new PdfPCell(new Paragraph(" ", new Font(bf, 12, Font.NORMAL)));
            cell27.setColspan(1);
            cell27.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell27);
            PdfPCell cell28 = new PdfPCell(new Paragraph(ObjectUtils.isEmpty(sorting.getSelf()) ? StringUtils.EMPTY : sorting.getSelf().stripTrailingZeros().toPlainString(), new Font(bf, 12, Font.NORMAL)));
            cell28.setColspan(1);
            cell28.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell28);
            PdfPCell cell29 = createBarcodeImage(writer, sorting.getKey());
            cell29.setColspan(4);
            cell29.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell29);
            //第六行
            PdfPCell cell31 = new PdfPCell(new Paragraph("订单号", new Font(bf, 12, Font.NORMAL)));
            cell31.setColspan(1);
            cell31.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell31);
            PdfPCell cell32 = new PdfPCell(new Paragraph("箱子数量", new Font(bf, 12, Font.NORMAL)));
            cell32.setColspan(1);
            cell32.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell32);
            PdfPCell cell33 = new PdfPCell(new Paragraph("体积", new Font(bf, 12, Font.NORMAL)));
            cell33.setColspan(1);
            cell33.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell33);
            PdfPCell cell34 = new PdfPCell(new Paragraph("仓库代码", new Font(bf, 12, Font.NORMAL)));
            cell34.setColspan(1);
            cell34.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell34);
            PdfPCell cell35 = new PdfPCell(new Paragraph("数量小计", new Font(bf, 12, Font.NORMAL)));
            cell35.setColspan(1);
            cell35.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell35);
            PdfPCell cell36 = new PdfPCell(new Paragraph("存储位置", new Font(bf, 12, Font.NORMAL)));
            cell36.setColspan(1);
            cell36.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell36);
            PdfPCell cell37 = new PdfPCell(new Paragraph("托盘数量", new Font(bf, 12, Font.NORMAL)));
            cell37.setColspan(1);
            cell37.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell37);
            PdfPCell cell38 = new PdfPCell(new Paragraph("外箱标记或说明", new Font(bf, 12, Font.NORMAL)));
            cell38.setColspan(1);
            cell38.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell38);
            //第七行
            List<ExportSortingDetailVo> detailList = detailInfoMap.get(sorting.getKey());
            //按照仓库代码的A-Z顺序来排序
            detailList.sort(Comparator.comparing(ExportSortingDetailVo::getWarehouseCode, Comparator.nullsLast(Comparator.naturalOrder())));
            Map<String, Long> warehouseCodeCountMap = detailList.stream().filter(Objects::nonNull).map(ExportSortingDetailVo::getWarehouseCode).filter(Objects::nonNull)
                    .collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
            Map<String, Integer> firstOccurrenceMap = new HashMap<>();
            for (int i = 0; i < detailList.size(); i++) {
                ExportSortingDetailVo detail = detailList.get(i);
                String warehouseCode = detail.getWarehouseCode();
                if (warehouseCode != null && !firstOccurrenceMap.containsKey(warehouseCode)) {
                    firstOccurrenceMap.put(warehouseCode, i);
                }
            }
            for (int i = 0; i < detailList.size(); i++) {
                ExportSortingDetailVo detail = detailList.get(i);
                PdfPCell cell39 = new PdfPCell(new Paragraph(detail.getOrderNo(), new Font(bf, 12, Font.NORMAL)));
                cell39.setColspan(1);
                cell39.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
                table.addCell(cell39);
                PdfPCell cell40 = new PdfPCell(new Paragraph(ObjectUtils.isEmpty(detail.getBoxesNo()) ? StringUtils.EMPTY : detail.getBoxesNo().stripTrailingZeros().toPlainString(), new Font(bf, 12, Font.NORMAL)));
                cell40.setColspan(1);
                cell40.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
                table.addCell(cell40);
                PdfPCell cell41 = new PdfPCell(new Paragraph(ObjectUtils.isEmpty(detail.getCbm()) ? StringUtils.EMPTY : detail.getCbm().stripTrailingZeros().toPlainString(), new Font(bf, 12, Font.NORMAL)));
                cell41.setColspan(1);
                cell41.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
                table.addCell(cell41);
                Integer i1 = firstOccurrenceMap.get(detail.getWarehouseCode());
                Long l = warehouseCodeCountMap.get(detail.getWarehouseCode());
                if (i1 == i) {
                    PdfPCell cell42 = new PdfPCell(new Paragraph(ObjectUtils.isEmpty(detail.getWarehouseCode()) ? StringUtils.EMPTY : detail.getWarehouseCode(), new Font(bf, 12, Font.NORMAL)));
                    cell42.setColspan(1);
                    cell42.setRowspan(Math.toIntExact(l));
                    cell42.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
                    cell42.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
                    table.addCell(cell42);
                    PdfPCell cell43 = new PdfPCell(new Paragraph(ObjectUtils.isEmpty(detail.getSubtotalQuantity()) ? StringUtils.EMPTY : detail.getSubtotalQuantity().stripTrailingZeros().toPlainString(), new Font(bf, 12, Font.NORMAL)));
                    cell43.setColspan(1);
                    cell43.setRowspan(Math.toIntExact(l));
                    cell43.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
                    cell43.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
                    table.addCell(cell43);
                    PdfPCell cell44 = new PdfPCell(new Paragraph(ObjectUtils.isEmpty(detail.getStorageLocation()) ? StringUtils.EMPTY : detail.getStorageLocation(), new Font(bf, 12, Font.NORMAL)));
                    cell44.setColspan(1);
                    cell44.setRowspan(Math.toIntExact(l));
                    cell44.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
                    cell44.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
                    table.addCell(cell44);
                    PdfPCell cell45 = new PdfPCell(new Paragraph(ObjectUtils.isEmpty(detail.getPalletsNo()) ? StringUtils.EMPTY : detail.getPalletsNo().stripTrailingZeros().toPlainString(), new Font(bf, 12, Font.NORMAL)));
                    cell45.setColspan(1);
                    cell45.setRowspan(Math.toIntExact(l));
                    cell45.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
                    cell45.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
                    table.addCell(cell45);
                }
                PdfPCell cell46 = new PdfPCell(new Paragraph(ObjectUtils.isEmpty(detail.getInstructions()) ? StringUtils.EMPTY : detail.getInstructions(), new Font(bf, 12, Font.NORMAL)));
                cell46.setColspan(1);
                cell46.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
                table.addCell(cell46);
            }
            document.add(table);
        } catch (DocumentException e) {
            log.error("error!", e);
            throw new ApiException(ResultCode.FAULT);
        }
        document.close();
        return pdfOutputStream.toByteArray();
    }

上面代码就是一行行的把值塞进去,

值得一提的是行合并,也就是几行明细对应一行的内容

代码 

按照仓库代码的A-Z顺序来排序 处
  • detailList 中的 ExportSortingDetailVo 对象将按照 warehouseCode 的字母表顺序进行排序,null 值排在最后。
  • warehouseCodeCountMap 是一个 Map<String, Long>,其中键是仓库代码,值是该仓库代码在 detailList 中出现的次数。
  • firstOccurrenceMap 是一个 Map<String, Integer>,其中键是仓库代码,值是该仓库代码在 detailList 中第一次出现的索引位置。

看这里可能有点不明白,看到效果图相信你会恍然大悟的

四 条形码工具类

    private PdfPCell createBarcodeImage(PdfWriter writer, String code) {
        Barcode128 barcode = new Barcode128();
        barcode.setCode(code);
        barcode.setCodeType(Barcode128.CODE128);
        barcode.setSize(12); // 设置条形码的字体大小
        barcode.setBaseline(10); // 设置基线位置
        barcode.setX(1.5f); // 设置条形码的宽度
        barcode.setBarHeight(50f); // 设置条形码的高度
 
        // 将条形码转换为 Image 对象
        Image barcodeImage = barcode.createImageWithBarcode(writer.getDirectContent(), null, null);
        PdfPCell cell = new PdfPCell(barcodeImage);
        cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
        return cell;
    }

五 效果图

大概是上面这个样子

具体图表根据实际业务进行构建代码

以上就是Java使用itext生成复杂数据的pdf的示例代码的详细内容,更多关于Java itext生成pdf的资料请关注脚本之家其它相关文章!

相关文章

  • Java拦截过滤器模式 (Intercepting Filter )实现方法

    Java拦截过滤器模式 (Intercepting Filter )实现方法

    拦截过滤器模式(Intercepting Filter Pattern)用于对应用程序的请求或响应做一些预处理/后处理,本文通过实例代码介绍Java拦截过滤器模式 (Intercepting Filter )的相关知识,感兴趣的朋友跟随小编一起看看吧
    2024-03-03
  • Assert.assertEquals的使用方法及注意事项说明

    Assert.assertEquals的使用方法及注意事项说明

    这篇文章主要介绍了Assert.assertEquals的使用方法及注意事项说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • Java实战个人博客系统的实现流程

    Java实战个人博客系统的实现流程

    读万卷书不如行万里路,只学书上的理论是远远不够的,只有在实战中才能获得能力的提升,本篇文章手把手带你用java+springboot+mybatis+redis+vue+elementui+Mysql实现一个个人博客系统,大家可以在过程中查缺补漏,提升水平
    2022-01-01
  • Java 实现限流器处理Rest接口请求详解流程

    Java 实现限流器处理Rest接口请求详解流程

    在工作中是否会碰到这样的场景,高并发的请求但是无法全部执行,需要一定的限流。如果你是使用的微服务框架,比如SpringCloud,可以使用Gateway增加限流策略来解决。本篇文章是在没有框架的情况实现限流器
    2021-11-11
  • Java 多线程并发LockSupport

    Java 多线程并发LockSupport

    这篇文章主要介绍了Java 多线程并发LockSupport,LockSupport 类是用于创建锁和其他同步类的基本线程阻塞原语,更多相关内容需要得小伙伴可以参考一下下面文章内容
    2022-06-06
  • SpringBoot依赖管理特性详解

    SpringBoot依赖管理特性详解

    Spring Boot自动引入依赖的版本信息可以在`spring-boot-starter-parent`和`spring-boot-dependencies`的pom文件中找到,如果需要修改依赖版本,可以在项目pom文件中添加覆盖配置项并刷新依赖即可
    2025-01-01
  • SpringBoot项目中使用Sharding-JDBC实现读写分离的详细步骤

    SpringBoot项目中使用Sharding-JDBC实现读写分离的详细步骤

    Sharding-JDBC是一个分布式数据库中间件,它不仅支持数据分片,还可以轻松实现数据库的读写分离,本文介绍如何在Spring Boot项目中集成Sharding-JDBC并实现读写分离的详细步骤,需要的朋友可以参考下
    2024-08-08
  • 如何使用 Spring Boot 搭建 WebSocket 服务器实现多客户端连接

    如何使用 Spring Boot 搭建 WebSocket 服务器实现多客户端连接

    本文介绍如何使用SpringBoot快速搭建WebSocket服务器,实现多客户端连接和消息广播,WebSocket协议提供全双工通信,SpringBoot通过@ServerEndpoint简化配置,支持实时消息推送,适用于聊天室或通知系统等应用场景
    2024-11-11
  • Flutter验证码输入框的2种方法实现

    Flutter验证码输入框的2种方法实现

    本文主要介绍了Flutter验证码输入框的2种方法实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • webservice实现springboot项目间接口调用与对象传递示例

    webservice实现springboot项目间接口调用与对象传递示例

    本文主要介绍了webservice实现springboot项目间接口调用与对象传递示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07

最新评论