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

Java使用itext生成pdf標(biāo)簽的操作方法

 更新時(shí)間:2024年12月15日 11:04:48   作者:Java小王子呀  
iText是著名的開(kāi)放源碼的站點(diǎn)sourceforge一個(gè)項(xiàng)目,是用于生成PDF文檔的一個(gè)java類(lèi)庫(kù),通過(guò)iText不僅可以生成PDF或rtf的文檔,而且可以將XML、Html文件轉(zhuǎn)化為PDF文件,本文給大家介紹了Java使用itext生成pdf標(biāo)簽的操作方法,需要的朋友可以參考下

一、利用Adobe Acrobat DC軟件創(chuàng)建pdf模板

備好Adobe Acrobat DC軟件

1.excel/jpg/png文件轉(zhuǎn)pdf文件

文件是正常的excel表格填上不會(huì)變動(dòng)的內(nèi)容

右擊打開(kāi)我們要轉(zhuǎn)換的文件

2.然后點(diǎn)擊添加域

3.可以看到域的名字

域的名字是和代碼里參數(shù)名是一致的

4.調(diào)整字體大小/對(duì)齊方式等

調(diào)整字體格式和大小,對(duì)其方式可靠上/居中/靠下

5.保存

ctrl + S 保存后放入項(xiàng)目模板路徑下

比如 resources - template 目錄下

二,代碼部分

首先

1.上依賴

            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itextpdf</artifactId>
                <version>${com.itextpdf.version}</version>
            </dependency>
 
<com.itextpdf.version>5.5.13.2</com.itextpdf.version>

2.Controller層

HttpServletResponse:用于將生成的 PDF 文件直接寫(xiě)入 HTTP 響應(yīng)流中,以便客戶端可以下載或查看 PDF 文件。

    @PostMapping(value = "printlabel/pallet", produces = MediaType.APPLICATION_PDF_VALUE)
    @ApiOperation(value = "打印托盤(pán)碼", produces = MediaType.APPLICATION_PDF_VALUE)
    public void printlabelPallet(@Valid @RequestBody PalletPrintRequest request, HttpServletResponse response) throws Exception {
        labelService.printlabelPallet(request, response);
    }

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

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

3.Service層

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

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

@Override
    @Lock4j
    @Transactional(rollbackFor = Exception.class)
    public void printlabelPallet(PalletPrintRequest request, HttpServletResponse response) throws Exception {
        Crossdock crossdock = new Crossdock();
        CrossdockPlanConsignee consignee = new CrossdockPlanConsignee();
        CrossdockPlan plan = new CrossdockPlan();
        //暫存
        if (request.getIsTemp()){
            crossdock = crossdockService.getByFieldValue(request.getOrderNo(), Crossdock::getOrderNo);
        }else{
            plan = planService.getByFieldValue(request.getPlanNo(),CrossdockPlan::getPlanNo);
            if (ObjectUtils.isEmpty(plan)){
                throw new ApiException(ResultCode.PARAMES_INVALID,"plan not found");
            }
            crossdock = crossdockService.getValidById(plan.getOrderId());
            consignee = planConsigneeService.getByFieldValue(plan.getId(), CrossdockPlanConsignee::getPlanId);
        }
        Customer customer = customerService.getValidById(crossdock.getCustomerId());
        //托盤(pán)標(biāo)號(hào)
        String consigneeName = consignee.getName() != null ? consignee.getName() : "";
        if (request.getIsCustomize() && StringUtils.isNotBlank(request.getPalletNo())){
            consigneeName = request.getPalletNo();
        }else if (request.getIsTemp()) {
            consigneeName += crossdock.getOrderNo();
            consigneeName += LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
            String redisKey = redisService.genKey(new String[]{NoRules.class.getSimpleName()}, consigneeName);
            redisService.setIfAbsent(redisKey, 0, NoRulesEnums.DateFormat.yyMMdd.getDays(), TimeUnit.DAYS);
            Long no = redisService.increment(redisKey);
            consigneeName = consigneeName + String.format("%0" + 5 + "d", no);
        }else {
            consigneeName += LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
            String redisKey = redisService.genKey(new String[]{NoRules.class.getSimpleName()}, consigneeName);
            redisService.setIfAbsent(redisKey, 0, NoRulesEnums.DateFormat.yyMMdd.getDays(), TimeUnit.DAYS);
            Long no = redisService.increment(redisKey);
            consigneeName = consigneeName + String.format("%0" + 5 + "d", no);
        }
        //托盤(pán)信息
        List<CrossdockPalletLabelNew> labelList = Lists.newArrayList();
        CrossdockPalletLabelNew palletLabel = new CrossdockPalletLabelNew().setCustomer(customer.getCode())
                .setPrintDate(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")))
                .setContainerNo(StringUtils.right(crossdock.getContainerNo(), 5))//取后5位
                .setTotalAmount(crossdock.getTotalAmount().stripTrailingZeros().toPlainString())// 轉(zhuǎn)運(yùn)單總箱數(shù)
                .setWarehouse(consignee.getName())// 收件人名稱
                .setPieces(request.getPieces().stripTrailingZeros().toPlainString())
                .setBarcode(consigneeName)
                .setPalletNO(consigneeName);
        labelList.add(palletLabel);
        //保存crossdock_plan_pallet
        BigDecimal palletCount = planPalletService.countByFieldValue(consigneeName, CrossdockPlanPallet::getPalletNo);
        if (palletCount.compareTo(BigDecimal.ZERO) <= 0) {
            CrossdockPlanPallet pallet = new CrossdockPlanPallet();
            pallet.setPalletNo(consigneeName).setOrderId(crossdock.getId()).setAmount(request.getPieces());
            if (ObjectUtils.isNotEmpty(plan) && StringUtils.isNotBlank(plan.getId())){
                pallet.setPlanId(plan.getId());
            }
            planPalletService.save(pallet);
        }else {
            throw new ApiException(ResultCode.FORBIDDEN,"msg:the_pallet_code_already_exists");
        }
        //保存crossdock_plan_pda
        BigDecimal pdaCount = planPdaService.countByFieldValue(consigneeName, CrossdockPlanPda::getPalletNo);
        if (pdaCount.compareTo(BigDecimal.ZERO) <= 0) {
            CrossdockPlanPda pda = new CrossdockPlanPda();
            pda.setPalletNo(consigneeName).setOrderNo(crossdock.getOrderNo()).setStatus(CrossdockEnums.PlanPdaStatus.INBOUND.name());
            if (ObjectUtils.isNotEmpty(plan) && StringUtils.isNotBlank(plan.getPlanNo())){
                pda.setPlanNo(plan.getPlanNo());
            }
            if(request.getIsTemp()){
                pda.setSourcePalletNo(PrintEnums.sourcePalletNo.STORAGE.name());
            }else {
                pda.setSourcePalletNo(PrintEnums.sourcePalletNo.PLAN.name());
            }
            planPdaService.save(pda);
        }else {
            throw new ApiException(ResultCode.FORBIDDEN,"msg:the_pallet_code_already_exists");
        }
        //保存托盤(pán)打印日志
        PalletPrintLogCreateRequest log = new PalletPrintLogCreateRequest().setOrderId(crossdock.getId())
                .setPalletNo(consigneeName)
                .setIsCustomize(request.getIsCustomize())
                .setPieces(request.getPieces());
        if (ObjectUtils.isNotEmpty(plan) && StringUtils.isNotBlank(plan.getId())){
            log.setPlanId(plan.getId());
        }
        palletPrintLogService.createPalletPrintLog(log);
        printPalletLabel(labelList, response.getOutputStream());
    }

這個(gè)是單個(gè)的,可以多個(gè),循環(huán)把數(shù)據(jù)放進(jìn)list即可

這里參數(shù)可以放進(jìn)list里,進(jìn)行批量生成并拼接到一個(gè)pdf里 

private final String TEMPLATE_FONT = "template/font/Alibaba-PuHuiTi-Medium.ttf";
private final String PALLET_TEMPLATE = "template/pallet.pdf";
private final int NUM_TO_PRINT = 2;
 
public void printPalletLabel(List<CrossdockPalletLabelNew> labelList, OutputStream outputStream) throws Exception {
    Document doc = new Document();
    PdfCopy copy = new PdfCopy(doc, outputStream);
    doc.open();
    
    // 創(chuàng)建字體
    BaseFont bf = BaseFont.createFont(TEMPLATE_FONT, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    
    // 遍歷標(biāo)簽列表
    for (CrossdockPalletLabelNew label : labelList) {
        // 每個(gè)標(biāo)簽打印 NUM_TO_PRINT 次
        for (int i = 0; i < NUM_TO_PRINT; i++) {
            // 創(chuàng)建字節(jié)數(shù)組輸出流
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            
            // 使用 PdfStamper 打開(kāi) PDF 模板
            PdfStamper stamper = new PdfStamper(new PdfReader(PALLET_TEMPLATE), bos);
            
            // 將標(biāo)簽對(duì)象轉(zhuǎn)換為 Map
            Map<String, Object> fieldMap = BeanMap.create(label);
            
            // 獲取 PDF 模板中的表單字段
            AcroFields fields = stamper.getAcroFields();
            
            // 添加自定義字體
            fields.addSubstitutionFont(bf);
            
            // 遍歷表單字段并填充內(nèi)容
            for (String key : fieldMap.keySet()) {
                if (key.equals(BARCODE)) {
                    // 如果是條形碼字段,調(diào)用 createBarcode 方法生成條形碼
                    createBarcode(stamper.getOverContent(1), label.getBarcode(), fields.getFieldPositions(BARCODE).get(0).position);
                } else {
                    // 否則,設(shè)置表單字段的值
                    fields.setField(key, Objects.toString(fieldMap.get(key), StringPool.EMPTY));
                }
            }
            
            // 平坦化表單,防止用戶編輯
            stamper.setFormFlattening(true);
            
            // 關(guān)閉 PdfStamper
            stamper.close();
            
            // 將生成的頁(yè)面添加到最終的 PDF 文檔中
            copy.addPage(copy.getImportedPage(new PdfReader(bos.toByteArray()), 1));
        }
    }
    
    // 關(guān)閉文檔
    doc.close();
}

循環(huán)兩次是業(yè)務(wù)需要,同一張打印兩次

字體可網(wǎng)上自行下載,或者更換其他字體

4.生成條形碼

這里可以設(shè)置具體的條形碼寬度/高度等,(條形碼下面默認(rèn)帶條形碼掃出來(lái)的內(nèi)容)

    private void createBarcode(PdfContentByte cb, String barcode, Rectangle position) throws DocumentException {
        Barcode128 barcode128 = new Barcode128();
        barcode128.setCode(barcode);
        barcode128.setX(1.7F);
        barcode128.setBarHeight(position.getHeight());
        Image image128 = barcode128.createImageWithBarcode(cb, null, null);
        image128.scaleToFit(position.getWidth(), position.getHeight());
        image128.setAbsolutePosition(position.getLeft() + (position.getWidth() - image128.getScaledWidth()) / 2,
                position.getBottom() + (position.getHeight() - image128.getScaledHeight()) / 2);
        cb.addImage(image128);
    }

三,標(biāo)簽效果圖

以上就是Java使用itext生成pdf標(biāo)簽的操作方法的詳細(xì)內(nèi)容,更多關(guān)于Java itext生成pdf標(biāo)簽的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • spring-core組件詳解——PropertyResolver屬性解決器

    spring-core組件詳解——PropertyResolver屬性解決器

    這篇文章主要介紹了spring-core組件詳解——PropertyResolver屬性解決器,需要的朋友可以參考下
    2016-05-05
  • 解析Spring?漏洞及其修復(fù)方案

    解析Spring?漏洞及其修復(fù)方案

    官宣了最近網(wǎng)傳的Spring漏洞。攻擊者利用該漏洞,可在未授權(quán)的情況下遠(yuǎn)程執(zhí)行命令,今天通過(guò)本文給大家普及下漏洞分析影響范圍及解決方案,感興趣的朋友跟隨小編一起看看吧
    2022-04-04
  • Java實(shí)現(xiàn)二分查找的變種

    Java實(shí)現(xiàn)二分查找的變種

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)二分查找的變種,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • javaweb中Http協(xié)議詳解

    javaweb中Http協(xié)議詳解

    HTTP是hypertext transfer protocol(超文本傳輸協(xié)議)的簡(jiǎn)寫(xiě),它是TCP/IP協(xié)議的一個(gè)應(yīng)用層協(xié)議,用于定義WEB瀏覽器與WEB服務(wù)器之間交換數(shù)據(jù)的過(guò)程。這篇文章主要為大家詳細(xì)介紹了javaweb中的Http協(xié)議,感興趣的小伙伴們可以參考一下
    2016-05-05
  • SpringSecurity6.0 如何通過(guò)JWTtoken進(jìn)行認(rèn)證授權(quán)

    SpringSecurity6.0 如何通過(guò)JWTtoken進(jìn)行認(rèn)證授權(quán)

    這篇文章主要介紹了SpringSecurity6.0 通過(guò)JWTtoken進(jìn)行認(rèn)證授權(quán)的過(guò)程,本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2025-04-04
  • Spring Boot與React集成的示例代碼

    Spring Boot與React集成的示例代碼

    這篇文章主要介紹了Spring Boot與React集成的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • Spring-cloud-eureka使用feign調(diào)用服務(wù)接口

    Spring-cloud-eureka使用feign調(diào)用服務(wù)接口

    這篇文章主要為大家詳細(xì)介紹了Spring-cloud-eureka使用feign調(diào)用服務(wù)接口,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • SpringMVC請(qǐng)求亂碼處理的2種方式

    SpringMVC請(qǐng)求亂碼處理的2種方式

    這篇文章主要介紹了SpringMVC請(qǐng)求亂碼處理的2種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Java實(shí)現(xiàn)經(jīng)典捕魚(yú)達(dá)人游戲的示例代碼

    Java實(shí)現(xiàn)經(jīng)典捕魚(yú)達(dá)人游戲的示例代碼

    《捕魚(yú)達(dá)人》是一款以深海狩獵為題材的休閑競(jìng)技游戲。本文將利用Java實(shí)現(xiàn)這一經(jīng)典的游戲,文中采用了swing技術(shù)進(jìn)行了界面化處理,需要的可以參考一下
    2022-02-02
  • 詳解springboot中redis的使用和分布式session共享問(wèn)題

    詳解springboot中redis的使用和分布式session共享問(wèn)題

    這篇文章主要介紹了詳解springboot中redis的使用和分布式session共享問(wèn)題,詳細(xì)的介紹了解決分布式系統(tǒng)的session如何共享問(wèn)題,有興趣的可以了解一下
    2017-11-11

最新評(píng)論