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的资料请关注脚本之家其它相关文章!

相关文章

  • 解决springmvc+mybatis+mysql中文乱码问题

    解决springmvc+mybatis+mysql中文乱码问题

    这篇文章主要介绍了解决java中springmvc+mybatis+mysql中文乱码问题的相关资料,需要的朋友可以参考下
    2015-09-09
  • MyBatis-Plus如何关闭SQL日志打印详解

    MyBatis-Plus如何关闭SQL日志打印详解

    在使用mybatisplus进行开发时,日志是一个非常有用的工具,它可以帮助我们更好地了解和调试我们的代码,这篇文章主要给大家介绍了关于MyBatis-Plus如何关闭SQL日志打印的相关资料,需要的朋友可以参考下
    2024-03-03
  • spring中BeanUtils.copyProperties的使用(深拷贝,浅拷贝)

    spring中BeanUtils.copyProperties的使用(深拷贝,浅拷贝)

    本文主要介绍了spring中BeanUtils.copyProperties的使用(深拷贝,浅拷贝),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • Java中将String类型依照某个字符分割成数组的方法

    Java中将String类型依照某个字符分割成数组的方法

    下面小编就为大家分享一篇Java中将String类型依照某个字符分割成数组的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • Spring Boot如何实现统一数据返回

    Spring Boot如何实现统一数据返回

    这篇文章主要介绍了Spring Boot如何实现统一数据返回,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-07-07
  • 如何在SpringBoot+Freemarker中获取项目根目录

    如何在SpringBoot+Freemarker中获取项目根目录

    这篇文章主要介绍了如何在SpringBoot+Freemarker中获取项目根目录的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • eclipse+myeclipse 环境配置方法

    eclipse+myeclipse 环境配置方法

    eclipse+myeclipse配置环境
    2009-07-07
  • Spring Boot Admin邮件警报整合过程解析

    Spring Boot Admin邮件警报整合过程解析

    这篇文章主要介绍了Spring Boot Admin邮件警报整合过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • SpringBoot整合Swagger3的流程详解

    SpringBoot整合Swagger3的流程详解

    这篇文章主要介绍了SpringBoot整合Swagger3的流程详解,Swagger最核心的类就是Docket、它可以配置作者信息、扫描类型,在SwaggerConfig配置类,添加@Configuration和@EnableOpenApi注解,需要的朋友可以参考下
    2024-01-01
  • SpringBoot链路追踪skyworking的接入方法

    SpringBoot链路追踪skyworking的接入方法

    在SpringBoot项目中引入SkyWalking进行链路追踪,需要下载探针jar包,配置logback.xml,设置启动变量,以实现服务调用监控和错误预警,本文给大家介绍SpringBoot链路追踪skyworking的接入方法,感兴趣的朋友一起看看吧
    2024-10-10

最新评论