欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java使用itext生成復(fù)雜數(shù)據(jù)的pdf的示例代碼

 更新時(shí)間:2024年12月15日 10:49:19   作者:Java小王子呀  
Apache iText 是一個(gè)開(kāi)源 Java 庫(kù),支持 PDF 文檔的開(kāi)發(fā)和轉(zhuǎn)換,在本教程中,我們將學(xué)習(xí)如何使用 iText 開(kāi)發(fā)可以創(chuàng)建、轉(zhuǎn)換和操作 PDF 文檔的 Java 程序,感興趣的小伙伴跟著小編一起來(lái)看看吧

首先,什么是Itext

Apache iText 是一個(gè)開(kāi)源 Java 庫(kù),支持 PDF 文檔的開(kāi)發(fā)和轉(zhuǎn)換。
在本教程中,我們將學(xué)習(xí)如何使用 iText 開(kāi)發(fā)可以創(chuàng)建、轉(zhuǎn)換和操作 PDF 文檔的 Java 程序。
Itext目前遵從AGPL開(kāi)源協(xié)議,AGPL 可以說(shuō)是最嚴(yán)格的 GPL 了,強(qiáng)傳染性,即使是 RPC 調(diào)用也會(huì)被感染,不發(fā)行軟件而是作為 web 服務(wù)對(duì)外提供也必須開(kāi)放源代碼
目前Itext有很多product開(kāi)始收費(fèi),但你所需的功能基本上open source都能滿足

特點(diǎn):

以下是 iText 庫(kù)的顯著特點(diǎn) −

  • Interactive − iText 為你提供類(API)來(lái)生成交互式 PDF 文檔。使用這些,你可以創(chuàng)建地圖和書籍。
  • Adding bookmarks, page numbers, etc − 使用 iText,你可以添加書簽、頁(yè)碼和水印。
  • Split & Merge − 使用 iText,你可以將現(xiàn)有的 PDF 拆分為多個(gè) PDF,還可以向其中添加/連接其他頁(yè)面。
  • Fill Forms − 使用 iText,你可以在 PDF 文檔中填寫交互式表單。
  • Save as Image − 使用 iText,你可以將 PDF 保存為圖像文件,例如 PNG 或 JPEG。
  • Canvas − iText 庫(kù)為您提供了一個(gè) Canvas 類,你可以使用它在 PDF 文檔上繪制各種幾何形狀,如圓形、線條等。
  • Create PDFs − 使用 iText,你可以從 Java 程序創(chuàng)建新的 PDF 文件。你也可以包含圖像和字體。
  • 下載地址:Examples

    iText官網(wǎng): 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 響應(yīng)流中,以便客戶端可以下載或查看 PDF 文件。

目前,方法聲明拋出了 Exception,這會(huì)導(dǎo)致所有未捕獲的異常都被拋出到客戶端。為了提高代碼的健壯性,建議捕獲特定的異常,并根據(jù)不同的異常類型返回適當(dāng)?shù)?HTTP 狀態(tài)碼和錯(cuò)誤信息。

例如,你可以使用 @ExceptionHandler 來(lái)捕獲常見(jiàn)的異常,如 IOException、DocumentException 等,并返回 500 Internal Server Error 或其他適當(dāng)?shù)捻憫?yīng)。

    @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層

按照業(yè)務(wù)邏輯從數(shù)據(jù)庫(kù)獲取數(shù)據(jù)并處理數(shù)據(jù),放到合適的對(duì)象里

(這里主要是和業(yè)務(wù)相關(guān),不必深究里面內(nèi)容,最后能得出需要的數(shù)據(jù)傳出即可)

@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());
        // 集裝箱編號(hào)/柜號(hào)、柜型
            List<Crossdock> crossdockList = crossdockService.listByFieldValueSet(idSet, Crossdock::getId);
            if (ObjectUtils.isEmpty(crossdockList)) {
                throw new ApiException(ResultCode.PARAMES_INVALID);
            }
            // 統(tǒng)計(jì)快遞、卡派、自提、存?zhèn)}數(shù)量
            List<CrossdockPlan> crossdockPlanByOrderList = crossdockPlanService.listByFieldValueSet(idSet, CrossdockPlan::getOrderId);
            Map<String, List<CrossdockPlan>> crossdockPlanOrderIdMap = crossdockPlanByOrderList.stream().collect(Collectors.groupingBy(CrossdockPlan::getOrderId));
            // 客戶id、公司
            // 客戶(發(fā)件人)信息 customerVo
            Set<String> customerIdSet = crossdockList.stream().map(Crossdock::getCustomerId).collect(Collectors.toSet());
            Map<String, Customer> customerMap = customerService.mapByFieldValueSet(customerIdSet, Customer::getId);
            // 箱數(shù)統(tǒng)計(jì),分揀表
            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);
            // 拼接參數(shù)
            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());
                }
                // 設(shè)置統(tǒng)計(jì)數(shù)量
                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);
                    }
                    // 總數(shù)
                    BigDecimal totalAmount = crossdockPlanList.stream().filter(crossdockPlan -> !ObjectUtils.isEmpty(crossdockPlan.getTotalAmount()))
                            .map(CrossdockPlan::getTotalAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                    exportSortingVo.setTotal(crossdock.getTotalAmount());       //這里設(shè)置的總箱數(shù)應(yīng)該是轉(zhuǎn)運(yùn)單里面的總箱數(shù)
                    // 留倉(cāng)/hold
                    BigDecimal warehouseAmount = crossdock.getTotalAmount().subtract(totalAmount);
                    exportSortingVo.setWarehouse(warehouseAmount);
                }
                exportSortingVoList.add(exportSortingVo);
                // 設(shè)置分揀詳細(xì)信息
                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);
    }

上面數(shù)據(jù)處理好放進(jìn)去然后繼續(xù)調(diào)用

 public void complexFill(List<ExportSortingVo> baseInfoList, Map<String, List<ExportSortingDetailVo>> detailInfoMap, HttpServletResponse response) throws IOException {
        byte[] pdfBytes = convertExcelToPdf(baseInfoList,detailInfoMap);
        // 設(shè)置響應(yīng)頭
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "attachment; filename="+detailInfoMap.keySet().iterator().next()+".pdf");
        // 獲取響應(yīng)輸出流
        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,但沒(méi)有處理其他可能的異常(如 NullPointerException 或 IllegalArgumentException)。建議捕獲特定的異常,并根據(jù)不同的異常類型返回適當(dāng)?shù)腻e(cuò)誤信息。

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);
            // 設(shè)置頁(yè)邊距
            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("客戶編號(hào):"+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("總數(shù)",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("柜號(hào):"+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("留倉(cāng)/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("拆柜開(kāi)始時(shí)間", 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("拆柜結(jié)束時(shí)間", 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("訂單號(hào)", new Font(bf, 12, Font.NORMAL)));
            cell31.setColspan(1);
            cell31.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell31);
            PdfPCell cell32 = new PdfPCell(new Paragraph("箱子數(shù)量", 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("倉(cāng)庫(kù)代碼", new Font(bf, 12, Font.NORMAL)));
            cell34.setColspan(1);
            cell34.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell34);
            PdfPCell cell35 = new PdfPCell(new Paragraph("數(shù)量小計(jì)", new Font(bf, 12, Font.NORMAL)));
            cell35.setColspan(1);
            cell35.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell35);
            PdfPCell cell36 = new PdfPCell(new Paragraph("存儲(chǔ)位置", new Font(bf, 12, Font.NORMAL)));
            cell36.setColspan(1);
            cell36.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell36);
            PdfPCell cell37 = new PdfPCell(new Paragraph("托盤數(shù)量", new Font(bf, 12, Font.NORMAL)));
            cell37.setColspan(1);
            cell37.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell37);
            PdfPCell cell38 = new PdfPCell(new Paragraph("外箱標(biāo)記或說(shuō)明", new Font(bf, 12, Font.NORMAL)));
            cell38.setColspan(1);
            cell38.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            table.addCell(cell38);
            //第七行
            List<ExportSortingDetailVo> detailList = detailInfoMap.get(sorting.getKey());
            //按照倉(cāng)庫(kù)代碼的A-Z順序來(lái)排序
            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();
    }

上面代碼就是一行行的把值塞進(jìn)去,

值得一提的是行合并,也就是幾行明細(xì)對(duì)應(yīng)一行的內(nèi)容

代碼 

按照倉(cāng)庫(kù)代碼的A-Z順序來(lái)排序 處
  • detailList 中的 ExportSortingDetailVo 對(duì)象將按照 warehouseCode 的字母表順序進(jìn)行排序,null 值排在最后。
  • warehouseCodeCountMap 是一個(gè) Map<String, Long>,其中鍵是倉(cāng)庫(kù)代碼,值是該倉(cāng)庫(kù)代碼在 detailList 中出現(xiàn)的次數(shù)。
  • firstOccurrenceMap 是一個(gè) Map<String, Integer>,其中鍵是倉(cāng)庫(kù)代碼,值是該倉(cāng)庫(kù)代碼在 detailList 中第一次出現(xiàn)的索引位置。

看這里可能有點(diǎn)不明白,看到效果圖相信你會(huì)恍然大悟的

四 條形碼工具類

    private PdfPCell createBarcodeImage(PdfWriter writer, String code) {
        Barcode128 barcode = new Barcode128();
        barcode.setCode(code);
        barcode.setCodeType(Barcode128.CODE128);
        barcode.setSize(12); // 設(shè)置條形碼的字體大小
        barcode.setBaseline(10); // 設(shè)置基線位置
        barcode.setX(1.5f); // 設(shè)置條形碼的寬度
        barcode.setBarHeight(50f); // 設(shè)置條形碼的高度
 
        // 將條形碼轉(zhuǎn)換為 Image 對(duì)象
        Image barcodeImage = barcode.createImageWithBarcode(writer.getDirectContent(), null, null);
        PdfPCell cell = new PdfPCell(barcodeImage);
        cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
        return cell;
    }

五 效果圖

大概是上面這個(gè)樣子

具體圖表根據(jù)實(shí)際業(yè)務(wù)進(jìn)行構(gòu)建代碼

以上就是Java使用itext生成復(fù)雜數(shù)據(jù)的pdf的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Java itext生成pdf的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java攔截過(guò)濾器模式 (Intercepting Filter )實(shí)現(xiàn)方法

    Java攔截過(guò)濾器模式 (Intercepting Filter )實(shí)現(xiàn)方法

    攔截過(guò)濾器模式(Intercepting Filter Pattern)用于對(duì)應(yīng)用程序的請(qǐng)求或響應(yīng)做一些預(yù)處理/后處理,本文通過(guò)實(shí)例代碼介紹Java攔截過(guò)濾器模式 (Intercepting Filter )的相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • Assert.assertEquals的使用方法及注意事項(xiàng)說(shuō)明

    Assert.assertEquals的使用方法及注意事項(xiàng)說(shuō)明

    這篇文章主要介紹了Assert.assertEquals的使用方法及注意事項(xiàng)說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Java實(shí)戰(zhàn)個(gè)人博客系統(tǒng)的實(shí)現(xiàn)流程

    Java實(shí)戰(zhàn)個(gè)人博客系統(tǒng)的實(shí)現(xiàn)流程

    讀萬(wàn)卷書不如行萬(wàn)里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+springboot+mybatis+redis+vue+elementui+Mysql實(shí)現(xiàn)一個(gè)個(gè)人博客系統(tǒng),大家可以在過(guò)程中查缺補(bǔ)漏,提升水平
    2022-01-01
  • Java 實(shí)現(xiàn)限流器處理Rest接口請(qǐng)求詳解流程

    Java 實(shí)現(xiàn)限流器處理Rest接口請(qǐng)求詳解流程

    在工作中是否會(huì)碰到這樣的場(chǎng)景,高并發(fā)的請(qǐng)求但是無(wú)法全部執(zhí)行,需要一定的限流。如果你是使用的微服務(wù)框架,比如SpringCloud,可以使用Gateway增加限流策略來(lái)解決。本篇文章是在沒(méi)有框架的情況實(shí)現(xiàn)限流器
    2021-11-11
  • Java?多線程并發(fā)LockSupport

    Java?多線程并發(fā)LockSupport

    這篇文章主要介紹了Java?多線程并發(fā)LockSupport,LockSupport?類是用于創(chuàng)建鎖和其他同步類的基本線程阻塞原語(yǔ),更多相關(guān)內(nèi)容需要得小伙伴可以參考一下下面文章內(nèi)容
    2022-06-06
  • SpringBoot依賴管理特性詳解

    SpringBoot依賴管理特性詳解

    Spring Boot自動(dòng)引入依賴的版本信息可以在`spring-boot-starter-parent`和`spring-boot-dependencies`的pom文件中找到,如果需要修改依賴版本,可以在項(xiàng)目pom文件中添加覆蓋配置項(xiàng)并刷新依賴即可
    2025-01-01
  • SpringBoot項(xiàng)目中使用Sharding-JDBC實(shí)現(xiàn)讀寫分離的詳細(xì)步驟

    SpringBoot項(xiàng)目中使用Sharding-JDBC實(shí)現(xiàn)讀寫分離的詳細(xì)步驟

    Sharding-JDBC是一個(gè)分布式數(shù)據(jù)庫(kù)中間件,它不僅支持?jǐn)?shù)據(jù)分片,還可以輕松實(shí)現(xiàn)數(shù)據(jù)庫(kù)的讀寫分離,本文介紹如何在Spring Boot項(xiàng)目中集成Sharding-JDBC并實(shí)現(xiàn)讀寫分離的詳細(xì)步驟,需要的朋友可以參考下
    2024-08-08
  • 如何使用?Spring?Boot?搭建?WebSocket?服務(wù)器實(shí)現(xiàn)多客戶端連接

    如何使用?Spring?Boot?搭建?WebSocket?服務(wù)器實(shí)現(xiàn)多客戶端連接

    本文介紹如何使用SpringBoot快速搭建WebSocket服務(wù)器,實(shí)現(xiàn)多客戶端連接和消息廣播,WebSocket協(xié)議提供全雙工通信,SpringBoot通過(guò)@ServerEndpoint簡(jiǎn)化配置,支持實(shí)時(shí)消息推送,適用于聊天室或通知系統(tǒng)等應(yīng)用場(chǎng)景
    2024-11-11
  • Flutter驗(yàn)證碼輸入框的2種方法實(shí)現(xiàn)

    Flutter驗(yàn)證碼輸入框的2種方法實(shí)現(xiàn)

    本文主要介紹了Flutter驗(yàn)證碼輸入框的2種方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • webservice實(shí)現(xiàn)springboot項(xiàng)目間接口調(diào)用與對(duì)象傳遞示例

    webservice實(shí)現(xiàn)springboot項(xiàng)目間接口調(diào)用與對(duì)象傳遞示例

    本文主要介紹了webservice實(shí)現(xiàn)springboot項(xiàng)目間接口調(diào)用與對(duì)象傳遞示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07

最新評(píng)論