Java使用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
一 上依赖
<!-- 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
来捕获常见的异常,如 IOException
、DocumentException
等,并返回 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的资料请关注脚本之家其它相关文章!