Java使用itext生成復雜數據的pdf的示例代碼
首先,什么是Itext
Apache iText 是一個開源 Java 庫,支持 PDF 文檔的開發(fā)和轉換。
在本教程中,我們將學習如何使用 iText 開發(fā)可以創(chuàng)建、轉換和操作 PDF 文檔的 Java 程序。
Itext目前遵從AGPL開源協議,AGPL 可以說是最嚴格的 GPL 了,強傳染性,即使是 RPC 調用也會被感染,不發(fā)行軟件而是作為 web 服務對外提供也必須開放源代碼
目前Itext有很多product開始收費,但你所需的功能基本上open source都能滿足
特點:
以下是 iText 庫的顯著特點 −
- Interactive − iText 為你提供類(API)來生成交互式 PDF 文檔。使用這些,你可以創(chuàng)建地圖和書籍。
- 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 程序創(chuàng)建新的 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 狀態(tài)碼和錯誤信息。
例如,你可以使用 @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層
按照業(yè)務邏輯從數據庫獲取數據并處理數據,放到合適的對象里
(這里主要是和業(yè)務相關,不必深究里面內容,最后能得出需要的數據傳出即可)
@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);
}
// 統計快遞、卡派、自提、存?zhèn)}數量
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);
// 箱數統計,分揀表
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);
}上面數據處理好放進去然后繼續(xù)調用
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;
}五 效果圖

大概是上面這個樣子
具體圖表根據實際業(yè)務進行構建代碼
以上就是Java使用itext生成復雜數據的pdf的示例代碼的詳細內容,更多關于Java itext生成pdf的資料請關注腳本之家其它相關文章!
相關文章
Java攔截過濾器模式 (Intercepting Filter )實現方法
攔截過濾器模式(Intercepting Filter Pattern)用于對應用程序的請求或響應做一些預處理/后處理,本文通過實例代碼介紹Java攔截過濾器模式 (Intercepting Filter )的相關知識,感興趣的朋友跟隨小編一起看看吧2024-03-03
Assert.assertEquals的使用方法及注意事項說明
這篇文章主要介紹了Assert.assertEquals的使用方法及注意事項說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05
SpringBoot項目中使用Sharding-JDBC實現讀寫分離的詳細步驟
Sharding-JDBC是一個分布式數據庫中間件,它不僅支持數據分片,還可以輕松實現數據庫的讀寫分離,本文介紹如何在Spring Boot項目中集成Sharding-JDBC并實現讀寫分離的詳細步驟,需要的朋友可以參考下2024-08-08
如何使用?Spring?Boot?搭建?WebSocket?服務器實現多客戶端連接
本文介紹如何使用SpringBoot快速搭建WebSocket服務器,實現多客戶端連接和消息廣播,WebSocket協議提供全雙工通信,SpringBoot通過@ServerEndpoint簡化配置,支持實時消息推送,適用于聊天室或通知系統等應用場景2024-11-11
webservice實現springboot項目間接口調用與對象傳遞示例
本文主要介紹了webservice實現springboot項目間接口調用與對象傳遞示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-07-07

