java使用itext生成pdf

一、利用Adobe Acrobat DC软件创建pdf模板


备好Adobe Acrobat DC软件

1.excel/jpg/png文件转pdf文件

右击打开我们要转换的文件

2.然后点击 添加 域

3.可以看到域的名字

4.调整字体大小/对齐方式等

5.保存

二,代码部分

首先

上依赖

            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itextpdf</artifactId>
                <version>${com.itextpdf.version}</version>
            </dependency>
Controller
    @PostMapping(value = "printlabel/pallet", produces = MediaType.APPLICATION_PDF_VALUE)
    @ApiOperation(value = "打印托盘码", produces = MediaType.APPLICATION_PDF_VALUE)
    public void printlabelPallet(@ApiParam @Valid @RequestBody PalletPrintRequest request, HttpServletResponse response) throws Exception {
        labelService.printlabelPallet(request, response);
    }
Service
@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());
        //托盘标号
        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);
        }
        //托盘信息
        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())// 转运单总箱数
                .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");
        }
        //保存托盘打印日志
        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());
    }
    public void printPalletLabel(List<CrossdockPalletLabelNew> labelList, OutputStream outputStream) throws Exception {
        Document doc = new Document();
        PdfCopy copy = new PdfCopy(doc, outputStream);
        doc.open();
        BaseFont bf = BaseFont.createFont(TEMPLATE_FONT, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        for (CrossdockPalletLabelNew label : labelList) {
            for(int i = 0; i < NUM_TO_PRINT; i++) {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                PdfStamper stamper = new PdfStamper(new PdfReader(PALLET_TEMPLATE), bos);
                Map<String, Object> fieldMap = BeanMap.create(label);
                AcroFields fields = stamper.getAcroFields();
                fields.addSubstitutionFont(bf);
                for (String key : fieldMap.keySet()) {
                    if (key.equals(BARCODE)) {
                        createBarcode(stamper.getOverContent(1), label.getBarcode(), fields.getFieldPositions(BARCODE).get(0).position);
                    } else {
                        fields.setField(key, Objects.toString(fieldMap.get(key), StringPool.EMPTY));
                    }
                }
                stamper.setFormFlattening(true);
                stamper.close();
                copy.addPage(copy.getImportedPage(new PdfReader(bos.toByteArray()), 1));
            }
        }
        doc.close();
    }
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;

生成条形码

    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);
    }

三,效果图

后面还会写复杂表格的填充并生成pdf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/922710.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

生成对抗网络模拟缺失数据,辅助PAMAP2数据集仿真实验

PAMAP2数据集是一个包含丰富身体活动信息的数据集&#xff0c;它为我们提供了一个理想的平台来开发和测试HAR模型。本文将从数据集的基本介绍开始&#xff0c;逐步引导大家通过数据分割、预处理、模型训练&#xff0c;到最终的性能评估&#xff0c;在接下来的章节中&#xff0c…

全面解析:HTML页面的加载全过程(一)--输入URL地址,与服务器建立连接

用户输入URL地址&#xff0c;与服务器建立连接 用户在浏览器地址栏输入一个URL 浏览器开始执行以下三步操作操作&#xff1a;url解析、DNS查询、TCP连接 第一步&#xff1a;URL解析 什么是URL&#xff1f; URL(Uniform Resource Locator&#xff0c;统一资源定位符)是互联网…

STM32总体架构简单介绍

目录 一、引言 二、STM32的总体架构 1、三个被动单元 &#xff08;1&#xff09;内部SRAM &#xff08;2&#xff09;内部闪存存储器 &#xff08;3&#xff09;AHB到APB的桥&#xff08;AHB to APBx&#xff09; 2、四个主动&#xff08;驱动&#xff09;单元 &#x…

postman 调用 下载接口(download)使用默认名称(response.txt 或随机名称)

官网地址&#xff1a;https://www.postman.com 介绍 Postman 是一款流行的 API 开发和测试工具&#xff0c;用于发送 HTTP 请求、测试接口、调试服务器响应以及进行 API 文档管理。它支持多种请求类型&#xff08;如 GET、POST、PUT、DELETE 等&#xff09;&#xff0c;并且功能…

JavaScript将至

JS是什么&#xff1f; 是一种运行在客户端&#xff08;浏览器&#xff09;的编程语言&#xff0c;实现人机交互效果 作用捏&#xff1f; 网页特效 (监听用户的一些行为让网页作出对应的反馈) 表单验证 (针对表单数据的合法性进行判断) 数据交互 (获取后台的数据, 渲染到前…

Vue.js 学习总结(13)—— Vue3 version 计数介绍

前言 Vue3.5 提出了两个重要概念&#xff1a;version计数和双向链表&#xff0c;作为在内存和计算方面性能提升的最大功臣。既然都重要&#xff0c;那就单挑 version 计数来介绍&#xff0c;它在依赖追踪过程中&#xff0c;起到快速判断依赖项有没有更新的作用&#xff0c;所以…

全面解析多种mfc140u.dll丢失的解决方法,五种方法详细解决

当你满心期待地打开某个常用软件&#xff0c;却突然弹出一个错误框&#xff0c;提示“mfc140u.dll丢失”&#xff0c;那一刻&#xff0c;你的好心情可能瞬间消失。这种情况在很多电脑用户的使用过程中都可能出现。无论是游戏玩家还是办公族&#xff0c;面对这个问题都可能不知所…

《Spring 实战:小型项目开发初体验》

一、引言 Spring 作为一款强大的 Java 开发框架&#xff0c;在小型项目开发中有着广泛的应用。本文将带你深入体验 Spring 在小型项目开发中的实战过程&#xff0c;从环境搭建到项目部署&#xff0c;全面展示 Spring 的魅力。 一、引言 Spring 作为一款强大的 Java 开发框架&…

Altium Designer学习笔记 11-15 原理图的封装 编译 检查 _PCB封装库的创建

基于Altium Designer 23学习版&#xff0c;四层板智能小车PCB 更多AD学习笔记&#xff1a;Altium Designer学习笔记 1-5 工程创建_元件库创建Altium Designer学习笔记 6-10 异性元件库创建_原理图绘制 目录 11、Value值的核对 12、封装的统一管理 13、原理图的编译设置和检查…

【Spring Boot】# 使用@Scheduled注解无法执行定时任务

1. 前言 在 Spring Boot中&#xff0c;使用Scheduled注解来定义定时任务时&#xff0c;定时任务不执行&#xff1b;或未在规定时间执行。 import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component;Component public c…

Spring Boot3远程调用工具RestClient

Spring Boot3.2之后web模块提供了一个新的远程调用工具RestClient&#xff0c;它的使用比RestTemplate方便&#xff0c;开箱即用&#xff0c;不需要单独注入到容器之中&#xff0c;友好的rest风格调用。下面简单的介绍一下该工具的使用。 一、写几个rest风格测试接口 RestCont…

VLAN是什么,一个好的网络为什么要划分VLAN呢?

前言 在上一篇中讲解了交换机的工作原理&#xff0c;知道了交换机处理数据的转发方式&#xff0c;其中有两种情况会以广播方式进行发送数据&#xff0c;第一种是目的MAC是全F的&#xff0c;以及组播MAC&#xff0c;第二种是未知单播帧&#xff0c;那这个会带来什么样的问题呢&…

flowable流程图详细绘制教程

文章目录 前言一、flowable是什么&#xff1f;回答下之前的问题 二、flowable-modeler使用1. 使用步骤2.开始绘制弄一个请假的流程 三 加载该流程总结 前言 flowable有些晦涩难懂的东西&#xff1a; 我最开始接触的时候,还是用的activity,当时觉得好复杂,那么这次经过我自己在…

蓝桥杯c++算法秒杀【6】之动态规划【上】(数字三角形、砝码称重(背包问题)、括号序列、组合数问题:::非常典型的必刷例题!!!)

下将以括号序列、组合数问题超级吧难的题为例子讲解动态规划 别忘了请点个赞收藏关注支持一下博主喵&#xff01;&#xff01;&#xff01;! ! ! ! &#xff01; 关注博主&#xff0c;更多蓝桥杯nice题目静待更新:) 动态规划 一、数字三角形 【问题描述】 上图给出了一…

[Python3学习笔记-基础语法] Python3 基础语法

本篇文章详细介绍Python3的基础语法&#xff0c;主要包括编码、标识符、Python保留字、注释、行缩进、多行语句、Number类型、字符串、空行、print打印等。 这些是Python最基础的东西&#xff0c;掌握好了才能更好的学习后续的内容。 有兴趣共同结伴学习Python的朋友&#xff0…

HDR视频技术之三:色度学与颜色空间

HDR 技术的第二个理论基础是色度学。从前面的内容中可以了解到&#xff0c;光学以及人类视觉感知模型为人类提供了解释与分析人类感知亮度的理论基础&#xff0c;但是 HDR 技术不仅仅关注于提升图像与视频的亮度范围&#xff0c;同时也关注于提供更加丰富的色彩。因此&#xff…

数据库MYSQL——表的设计

文章目录 前言三大范式&#xff1a;几种实体间的关系&#xff1a;一对一关系&#xff1a;一对多关系&#xff1a;多对多关系&#xff1a; 前言 之前的博客中我们讲解的是关于数据库的增删改查与约束的基本操作&#xff0c; 是在已经创建数据库&#xff0c;表之上的操作。 在实…

C++自动化测试:GTest 与 GitLab CI/CD 的完美融合

在现代软件开发中&#xff0c;自动化测试是保证代码质量和稳定性的关键手段。对于C项目而言&#xff0c;自动化测试尤为重要&#xff0c;它能有效捕捉代码中的潜在缺陷&#xff0c;提高代码的可维护性和可靠性。本文将重点介绍如何在C项目中结合使用Google Test&#xff08;GTe…

备忘笔记-工具:JetBrains友好工具安装配置

1、配置/脚本文件下载 1、校验地址&#xff1a;https://3.jetbra.in/ 打开选择可用链接&#xff0c;点击跳转可用页面。 2、下载文件 左上角点击下载jetbra.zip文件 下载对应全家桶软件版本号&#xff0c;版本号在对应卡票右上角可见。 2、安装包下载 官网地址&#xff1a…

Flask 基于wsgi源码启动流程

1. 点击 __call__ 进入到源码 2. 找到 __call__ 方法 return 执行的是 wsgi方法 3. 点击 wsgi 方法 进到 wsgi return 执行的是 response 方法 4. 点击response 方法 进到 full_dispatch_request 5. full_dispatch_request 执行finalize_request 方法 6. finalize_request …