java使用world模板动态生成PDF文件

news2025/2/28 3:17:55

根据项目需求,需要用到一个功能,根据页面参数需要动态的生成一个world,并将world生成两份PDF文件,一份正式文件,一份临时的电子文件(带有二维码,扫描可以下载正式文件的电子版本)。同时上传到文件存储服务器minio上,下面介绍具体的实现步骤

1、首先准备一个world模板,新建一个world如下图所示

在需要动态填入数据的地方采用字母代替(此处注意,字母需要大写),用于占位操作。

2、编辑代码,项目接口,我采用的是一般的是SpringBoot项目结构,具体不多述,下面贴出关键代码:①根据接口获取到的参数,来开始命名最后要生成的pdf文件

 scXwblPdfRequest  是接口传来的实体形的参数

 //生成文件名
  String pdfName = FileUpload.aliyungenFileNameNew("文档名_"+scXwblPdfRequest.getWorkUnit()+"_"+scXwblPdfRequest.getName());
  String fileName = pdfName + "_2.pdf";
  String fileNameZswj = pdfName+".pdf";

②准备文件

String pdfUrl = fwurl  +bucketName+Constants.SPRIT+ fileName;
String pdfUrlZswj = fwurl +bucketName+Constants.SPRIT+ fileNameZswj;
//获取本地准备的world模板
String mblj = "file/xwbl_1.doc";
Map<String , String> textMap = createXwblTextMap(scXwblPdfRequest );
//设置pdf的文件地址(含二维码)
String pdfUrl = fwurl  +bucketName+Constants.SPRIT+ fileName;
//设置pdf的正式文件地址(不含二维码)
String pdfUrlZswj = fwurl +bucketName+Constants.SPRIT+ fileNameZswj;

方法说明:createXwblTextMap是将接口传来的实体参数,进行处理,以map形式处理好

//构造textMap
    public Map createXwblTextMap(ScXwblPdfRequest  xwblPdfRequest){
        Map<String , String> textMap = new HashMap<>();
        //开始时间
        textMap.put("STIME",String.valueOf(xwblPdfRequest.getStartTime()));
        //结束时间
        textMap.put("ETIME",String.valueOf(xwblPdfRequest.getEndTime()));
        //地点
        textMap.put("XWADRESS",xwblPdfRequest.getXwadress());
        //姓名
        textMap.put("NAME",xwblPdfRequest.getName());
        //性别
        textMap.put("SEX",xwblPdfRequest.getSex());
        return textMap;
    }

3、文件的其他信息处理,uploadforXwblUrl:是处理world完成后生成含有二维码的pdf文件,XwblzswjUrl :是处理world完成后生成不含有二维码的pdf文件

//保存两个pdf,一个含二维码的临时文件,一个正式文件
 //加了二维码,用于扫码下载   (pdfUrlZswj  用于给二维码下载地址)
 textMap.put("EWMTIPS","扫描二维码查看、下载正式文件");
//不带二维码的地址
 String withoutEwmUrl = pdfUrlZswj;
 String  uploadforXwblUrl   = xwblcs(bucketName,textMap  , pdfUrl , fileName , true , mblj , withoutEwmUrl );
 //没有二维码
 textMap.put("EWMTIPS","");
 String  XwblzswjUrl = xwblcs(bucketName,textMap  , pdfUrlZswj , fileNameZswj , false , mblj ,"");
 result.put("uploadforXwblUrl",uploadforXwblUrl);
 result.put("XwblzswjUrl", XwblzswjUrl);

方法说明:xwblcs作用:主要用于生成PDF文件

//生成PDF文件
    public String xwblcs(String bucketName,Map<String , String> textMap  , String pdfUrl ,String fileName , boolean ewm  , String mbwj ,String withoutEwmUrl ){
        try{
            MinioUtils minio = new MinioUtils();
            //读取doc模板文件
            ClassPathResource classPathResource = new ClassPathResource(mbwj);
            Document doc = new Document(classPathResource.getInputStream());
            DocumentBuilder builder = new DocumentBuilder(doc);
            //关闭文件流
            classPathResource.getInputStream().close();
            //向文档中插入文字
            AsposeUtil.docTextReplace(doc , textMap);
            //插入二维码
            if(ewm){
                AsposeUtil.docEwmReplace(builder ,withoutEwmUrl);
            }
            OutputStream  outputStreamPdf= new ByteArrayOutputStream(1024);
            doc.save(outputStreamPdf, SaveFormat.PDF);
            ByteArrayOutputStream baosPdf = (ByteArrayOutputStream) outputStreamPdf ;
            ByteArrayInputStream inputStreamPdf = new     
            ByteArrayInputStream(baosPdf.toByteArray());
            /**生成好的PDF文件上传到minio**/
            minio.putObject(bucketName,fileName,inputStreamPdf,"application/pdf");
            //关闭流
            baosPdf.close();
            inputStreamPdf.close();
            outputStreamPdf.close();
            /**生成的刚上传的PDF文件返文件路径**/
            return pdfUrl;
        }catch (Exception e){
            log.error(e.toString());
            throw new BussinessException(BizExceptionEnum.PDF_ERROR);
        }
    }

AsposeUtil:工具类,用于处理文字、图片插入插入文档,贴代码

@Slf4j
public class AsposeUtil {
    /**
     * word转pdf
     */
    public static void docToPdf(String intPath, String outPath) throws Exception {
        Document doc = new Document(intPath);
        FileOutputStream os = null;
        //新建一个pdf文档
        //File file = new File(outPath);
        //os = new FileOutputStream(file);
        //保存为pdf文件,saveFormat取的是words包下的,值为:40
        doc.save(outPath);
        //os.close();
    }

    public static void docTextReplace(Document doc, Map<String, String> textMap) throws Exception {
        Range range = doc.getRange();
        for (Map.Entry<String, String> entry : textMap.entrySet()) {
            range.replace(entry.getKey(), entry.getValue(), true, false);
        }
    }

    public static void docEwmReplace(DocumentBuilder builder , String pdfUrl) throws Exception {
        //读取用于放在二维码中间的图片
        ClassPathResource classPathResource1 = new ClassPathResource("file/ewmLogo.jpg");
        OutputStream  outputStream = new ByteArrayOutputStream(1024);
        QRCodeUtil.encode(pdfUrl, classPathResource1.getInputStream(),outputStream , true);
        classPathResource1.getInputStream().close();
        ByteArrayOutputStream baos = (ByteArrayOutputStream) outputStream ;
        ByteArrayInputStream inputStream = new ByteArrayInputStream(baos.toByteArray());
        //插入二维码
        builder.moveToBookmark("EWM");
        builder.insertImage(inputStream , 150 , 150);
        outputStream.close();
        baos.close();
        inputStream.close();
        inputStream.close();
    }

}

这里需要注意的是。在这个工具类中,有向world中插入图片的操作,builder.moveToBookmark("EWM");,这里插入进去的图片,不是用占位符去对应的,而是在world模板中需要插入一个名为“EWM”的书签,

 最后流程介绍到此结束。最后用接口工具调用该接口,会返回两个地址,一个带二维码。一个不带二维码

 

最后访问minio的地址获取到两个pdf文件。同时手机或者pad,扫描带有二维码的pdf上的二维码,也能下载不带二维码,用于打印的文档

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JAVA开发(nginx)

主要描述下面4个内容&#xff1a; 1.Nginx的正向代理和反向代理 2.Nginx的动静分离 3.Nginx的负载均衡 4.Nginx的配置详解 解释&#xff1a; Nginx的正向代理&#xff1a;代理的是客户端。 Nginx的反向代理&#xff1a;代理的是服务端。在web服务中&#xff0c;一般都是…

2022年“网络安全”赛项驻马店市赛选拔赛 任务书

2022年“网络安全”赛项驻马店市赛选拔赛 一、竞赛时间 共计3小时。 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段单兵模式系统渗透测试 任务一 Windows操作系统渗透测试 100分钟 100 任务二 Linux操作系统渗透测试 150 任务三 数字取证调查 150 任务四 …

vscode不能打开终端问题

遇到vscode不能打开终端问题&#xff0c;一直以为是安全软件限制问题&#xff0c;也没搜到解决方案&#xff0c;因为影响也不大&#xff0c;就没有管。 最近&#xff0c;要用vscode调试代码&#xff0c;发现不能打开终端&#xff0c;没法玩了&#xff0c;又来看这个问题&#…

【图像隐藏】基于matlab像素预测和位平面压缩的加密图像可逆数据隐藏【含Matlab源码 2218期】

⛄一、加密图像可逆数据隐藏简介 1 信息隐藏技术概述 信息隐藏技术是把秘密信息隐藏在多媒体信息中的一种方法。图像是最适合信息隐藏的数据载体。信息隐藏的方法主要有数字水印技术、隐写术等。 信息隐藏可以分为有损信息隐藏与可逆信息隐藏信息隐藏技术, 区别在于接收端是否…

【虚幻引擎UE】UE5 简单实现范围计算圆圈绘制

先来看看可以实现的效果&#xff1a; 一、实现快速绘制圆圈的C函数 .cpp文件 #include "drawPolygon.h" #include "Components/LineBatchComponent.h" #include "Engine/World.h" #include "EngineGlobals.h" #include "Prim…

墨西哥专线详解:墨西哥专线时效多久,墨西哥专线价格多少?

墨西哥专线是国内直飞墨西哥或者海运墨西哥的专线物流服务&#xff0c;从中国到墨西哥的物流大约需要3到30天。不同的运输方式到墨西哥的时间不同。国际快递是最快的。通常3到5天就可以完成目的地派送&#xff0c;最慢的是海运专线&#xff0c;到墨西哥大约需要20到30天才能到达…

隐式神经表示二:超分网络学习傅里叶系数Local Texture Estimator for Implicit Representation Function

文章目录1. Local Texture Estimator for Implicit Representation Function1. 通过隐式神经网络表示方法 实现 超分辨率。2. 在编码器和解码器之间作者引入一个 local texture estimator3. 代码分析整体框架生成图像特征&#xff0c;编码器是一个常规的卷积网络&#xff0c;文…

【Pytorch with fastai】第 8 章 :协同过滤深入探讨

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

十四、Java String 类

Java String 类 字符串广泛应用 在 Java 编程中&#xff0c;在 Java 中字符串属于对象&#xff0c;Java 提供了 String 类来创建和操作字符串。 创建字符串 创建字符串最简单的方式如下: String str "xxx"; 在代码中遇到字符串常量时&#xff0c;这里的值是 &q…

大数据开源平台好在哪里?

当前是大数据发展时代&#xff0c;对于企业而言需要紧紧抓住契机乘势而上&#xff0c;利用好内部数据做好数字化转型&#xff0c;可以为企业带来更高的发展空间。大数据开源平台是助力企业提升办公效率的软件平台&#xff0c;那么&#xff0c;哪里有这样的大数据开源平台&#…

关于Git使用:fatal: Could not read from remote repository.的报错问题解决

目录 一&#xff1a;问题描述 二&#xff1a;解决过程 1&#xff0c;增加账号及邮箱 2&#xff0c;添加秘钥&#xff1a; 3&#xff0c;获取公钥并将其设置到云效里面 4&#xff0c;宝塔终端 解除密码 三&#xff1a;解决截图 一&#xff1a;问题描述 我们公司的版本仓…

【布隆过滤器】世界上大概有1 亿种小蛋糕,客户康宝要求这辈子不吃重复的小蛋糕。

文章目录需求概念思想问题优点缺点应用手写布隆过滤器补充需求 现在客户康宝有一个需求&#xff1a;世界上大概有 1 亿 种小蛋糕&#xff0c;康宝要求这辈子不吃重复种类的小蛋糕。 因为小蛋糕的种类很大可能只会增加&#xff0c;而不会减少&#xff0c;面对这种大数据量的要…

静态分析 Qt Ceator 组织的工程代码

文章目录Missing reference in range-for with non trivial type (QString) [clazy-range-loop]Slots named on_foo_bar are error prone [clazy-connect-by-name]Call to virtual method FlowLayout::takeAt during destruction bypasses virtual dispatch [clang-analyzer-op…

目的和目标的差异|丰田自动工程完结的目的、目标、应用化的意义和明确、二

目的和目标的差异|丰田自动工程完结的目的、目标、应用化的意义和明确、二 业务的方式改废|工作的目的、目标、输出的明确化 业务改善的一种方法被称为业务改废。意思是更好地改善现有的业务&#xff0c;废除不必要的业务。 使用这种方法&#xff0c;首先要明确想要改变和废除…

初学Java,遇错就懵,这类问题到底怎么处理呢?!

前言 众所周知&#xff0c;壹哥在干Java的路上已经越走越远&#xff0c;越陷越深&#xff0c;最近无意刷知乎时看到一位初学Java的迷惑少年&#xff0c;被报错干懵啦&#xff01;&#xff01;&#xff01; 初学Java的同学&#xff0c;遇到报错一定不要慌&#xff0c;首先检查…

Android App规范处理中版本设置、发布模式、给数据集SQLite加密的讲解及使用(附源码 超详细必看)

运行有问题或需要源码请点赞关注收藏后评论区留言~~~ 一、版本设置 每个App都有三个基础信息&#xff0c;第一个是App的图标&#xff0c;第二个是App的名称&#xff0c;第三个是App的版本号。 一旦安装了某个版本的App&#xff0c;那么之后只能安装版本更新的同名App&#xf…

[公派访问学者]申请条件及选拔方法

国家公派访问学者绝大多数是经过层层选拔的&#xff0c;那么具体有哪些条件呢?又是如何选拔的呢?知识人网访问学者申请咨询老师和大家分享以下这篇文章。 一、申请条件 1、高级研究学者 申请时年龄不超过55岁。教学科研人员应为教授、博士生导师。申请人须同时具备以下条件…

基础类型存放在栈上,引用类型存放在堆上,请问是为什么? 字符串是存放在栈上么?

基础类型存放在栈上&#xff0c;引用类型存放在堆上&#xff0c;请问是为什么&#xff1f; 记住一句话&#xff1a;能量是守衡的&#xff0c;无非是时间换空间&#xff0c;空间换时间的问题 堆比栈大&#xff0c;栈比堆的运算速度快&#xff0c;对象是一个复杂的结构&#xf…

苹果手机和电脑怎么录屏?详细教程来了!

​相信小伙伴身边有不少人使用的是苹果手机和电脑。安卓手机和windows电脑怎么录屏不少人都已经知道了&#xff0c;那么苹果手机和电脑怎么录屏 呢&#xff1f;现在&#xff0c;小编就来详细的教教大家如何录屏&#xff0c;快拿出小本本记下来哦&#xff01; 一&#xff0e;苹…