Java套红:指定位置合并文档-NiceXWPFDocument

news2024/11/15 3:27:55

需求:做个公文系统,需要将正文文档在某个节点点击套红按钮,实现文档套红
试了很多方法,大多数网上能查到但是实际代码不能找到关键方法,可能是跟包的版本有关系,下面记录能用的这个。

一:添加依赖

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
                        <version>4.1.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
            <version>1.9.1</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-log4j12</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>e-iceblue</groupId>
            <artifactId>spire.doc</artifactId>
            <version>12.6.2</version>
        </dependency>

二、文档

模板:{{date}}是可以获取到的变量
在这里插入图片描述
文档:
在这里插入图片描述

三、代码

public static void word2RedDocument(String content, Map<String, Object> data, String destDocx) throws Exception {
        //模板文件地址
        String model = "D:\\套红模板.docx";
        //模板文件 参数填写
        XWPFTemplate template = XWPFTemplate.compile(model).render(data);
        //获取模板文件  公文
         NiceXWPFDocument main = template.getXWPFDocument();
         //正文文档
        NiceXWPFDocument sub = new NiceXWPFDocument(new FileInputStream(content));
        List<XWPFParagraph> paragraphs = main.getParagraphs();
        NiceXWPFDocument newDoc = new NiceXWPFDocument();
        for (XWPFParagraph p:paragraphs
             ) {
            if( null != p && p.getText().contains("正文")){
            //这里是要去掉正文两个字,自己debug看了索引,为了保险起见应该遍历run判断
               p.removeRun(0);
               XWPFRun run = p.createRun();
               // 合并两个文档到指定位置
              newDoc = main.merge(Arrays.asList(sub),run);
                break;
           }
        }

        // 设置页码--开始--没有需求可以删掉
        XWPFFooter footer = newDoc.createFooter(HeaderFooterType.DEFAULT);//创建一个新的XWPFFooter对象
        XWPFParagraph paragraph = footer.createParagraph();//创建新的XWPFParagraph对象
        paragraph.setAlignment(ParagraphAlignment.CENTER);//设置样式居中
        //设置段落对象
        XWPFRun runPre = paragraph.createRun();//新的段落对象
        runPre.setText("- ");
        XWPFRun run = paragraph.createRun();//新的段落对象
        CTFldChar fldChar = run.getCTR().addNewFldChar();//新的CTFldChar对象
        fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));
        CTText ctText = run.getCTR().addNewInstrText();
        ctText.setStringValue("PAGE  \\* MERGEFORMAT");
        ctText.setSpace(SpaceAttribute.Space.Enum.forString("preserve"));
  		fldChar = run.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.Enum.forString("end"));
        //设置段落对象
        XWPFRun runSuf = paragraph.createRun();//新的段落对象
        runSuf.setText(" -");
        // 将页脚添加到所有的页面
        XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(newDoc);
        headerFooterPolicy.createFooter(STHdrFtr.DEFAULT, new XWPFParagraph[]{paragraph});
// 设置页码--结束--没有需求可以删掉

		//可以是生成新文档,也可以生成到原来的正文
        content = "D:\\新文档.docx";



        // 生成新文档
        FileOutputStream out = new FileOutputStream(content);
        newDoc.write(out);
        newDoc.close();
        out.close();
        //doc转pdf
        doc2Pdf(content);
//        ByteArrayOutputStream os = new ByteArrayOutputStream();
//        newDoc.write(os);
//        InputStream is = new ByteArrayInputStream(os.toByteArray());
//        os.close();
    }

调用方法测试

 public static void main(String[] args) throws Exception {
        String sourceFile = "D:\\模板.docx";
        String targetFile = "D:\\测试.docx";
        Map<String, Object> data = new HashMap<>(2);
        List<String> list = Arrays.asList("技术", "测试", "评选结果", "测试", "评选结果", "测试", "评选结果");
        StringBuilder builder = new StringBuilder();
        for (int i =0;i<list.size();i++) {
            builder.append(list.get(i));
            if (i != list.size() -1){
                builder.append("  ");
            }
        }
        data.put("num", "931");
        data.put("year", "2024");
        data.put("name", "销售中心销售中心销售中心销售中心销售中心销售中心销售中心销售中心销售中心销售中心销售中心销售中心销售中心销售中心销售中心销售中心销售中心");
        data.put("keyword",builder );
//        data.put("keyword", Arrays.asList("技术","测试","评选结果","测试","评选结果","测试","评选结果"));
//        data.put("keyword", Arrays.asList("技术","测试"));
        data.put("user", "李斯");
//        data.put("company", "股份有限公司技术股份有限公司");
        data.put("date", getChineseDate());
        word2RedDocument(targetFile,data,"新文档.docx");
    }

转换时间的方法

public static String getChineseDate() {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日", Locale.CHINA);
        String date = sdf.format(cal.getTime());

        // 将数字转换为汉字
        String[] chineseNumbers = {"〇", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
        StringBuilder chineseDate = new StringBuilder();
        for (int i = 0; i < date.length(); i++) {
            if(i==4 || i==7 || i==10){
                chineseDate.append(date.charAt(i));
            } else {
                int number = Character.getNumericValue(date.charAt(i));
                if(i==5 || i==8 ){
                    if(number==0){
                        continue;
                    }
                }
                chineseDate.append(chineseNumbers[number]);
            }
        }

        return chineseDate.toString();
    }

执行方法:
在这里插入图片描述
结果文档如下:
在这里插入图片描述

XWPFDocument类相关:

在这里插入图片描述

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

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

相关文章

《C++20设计模式》命令模式思考

文章目录 一、前言二、分析 拆解1、经典命令模式2、撤销操作3、关于Invoker类 三、实现 一、前言 哎&#xff01;只要是书上写的和经典设计模式不同&#xff0c;我就会很伤脑筋。&#x1f629; 命令模式到底是干什么的&#xff1f; 答&#xff1a;命令的发送者和接收者完全解…

“一稿多投”是学术不端,还是作者的合法权利?

【SciencePub学术】“一稿多投”一直被认为是不端的行为&#xff0c;但这个“规矩”是在纸质时代信息沟通不畅的情况下制定的&#xff0c;近年来有关取消这一观念的声音已振聋发聩&#xff01; 詹启智的《一稿多投是著作权人依法享有的合法权利一一兼论一稿多发后果的规制》一文…

SpringBoot项目——送水管理系统

1、导入坐标 坐标作用pagehelper-spring-boot-startermybatis分页插件spring-boot-starter-thymeleafJSP模板引擎mybatis-spring-boot-startermybatisspring-boot-starter-webwebspring-boot-starter-testtestlombok不需要再写getter、setter或equals方法&#xff0c;只要有一…

建立有效的DNS性能检测机制

今天来分享如何建立有效的DNS性能监测机制&#xff0c;实时或定期监测关键指标。 一、建立DNS性能监测机制 &#xff08;一&#xff09;选择合适的监测工具 市场上有多种DNS性能监测工具可供选择&#xff0c;如IP数据云DNS检测功能。其具备强大的功能&#xff0c;能够针对多种…

简过网:快来看看你的专业能考哪个类型的事业单位?

你的专业能考哪个类型的事业单位&#xff0c;你知道吗&#xff1f;想考事业单位的姐妹&#xff0c;一定要在备考之前&#xff0c;查清楚你的专业适不适合考事业单位、考哪类事业编以及能报考哪些岗位&#xff1f;这个才能上岸的几率更高一些&#xff01; 事业单位有5类岗位&am…

Java动态执行jar包中类的方法

动态加载执行jar包&#xff0c;在实际开发中经常会需要用到&#xff0c;尤其涉及平台和业务的关系的时候&#xff0c;业务逻辑部分可以独立出去交给业务方管理&#xff0c;业务方只需要提供jar包&#xff0c;就能在平台上运行。 结论 通过反射可以实现动态调用jar包中的类的方…

免费可商用的Navicat Premium Lite要不要用?小心收到律丝函!

作者公众号&#xff1a;霸王龙的日常 专注数据库&#xff0c;分享实用的项目实战经验。 上周五写了一篇关于Navicat Premium Lite的文章&#xff0c;有网友去官网下载&#xff0c;反馈当前官网Navicat Premium Lite简介和我之前文章中的介绍的有出入。 我赶紧打开网站看了下Na…

修改CentOS7.9跟Unbantu24的ip地址

修改CentOS的IP地址 ip addr 查看IP地址 cd /etc/sysconfig/network-scripts ls vi ifcfg-ens33修改ip地址跟干网关地址 TYPE"Ethernet" PROXY_METHOD"none" BROWSER_ONLY"no" BOOTPROTO"static" DEFROUTE"yes" IPV4_FA…

排序 -- 手撕归并排序(递归和非递归写法)

一、基本思想 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每个子序列有…

掌上教务系统-计算机毕业设计源码84604

摘要 在数字化教育日益成为主流的今天&#xff0c;教务管理系统的智能化和便捷性显得尤为重要。为满足学校、教师、学生及家长对教务管理的高效需求&#xff0c;我们基于Spring Boot框架设计并实现了一款掌上教务系统。该系统不仅具备课程分类管理功能&#xff0c;使各类课程信…

软件架构之开发方法

软件架构之开发方法 第6章&#xff1a;开发方法6.1 软件生命周期6.2 软件开发模型6.2.1 瀑布模型6.2.2 演化模型6.2.3 螺旋模型6.2.4 增量模型6.2.5 构件组装模型 6.3 统一过程6.4 敏捷方法6.4.1 极限编程6.4.2 特征驱动开发6.4.3 Scrum6.4.4 水晶方法6.4.5 其他敏捷方法 6.5 软…

《梦醒蝶飞:释放Excel函数与公式的力量》9.5 IRR函数

9.5 IRR函数 IRR函数是Excel中用于计算内部收益率&#xff08;Internal Rate of Return, IRR&#xff09;的函数。内部收益率是评估投资项目盈利性的重要指标&#xff0c;它表示使投资项目的净现值&#xff08;NPV&#xff09;为零的折现率。 9.5.1 函数简介 IRR函数通过一系…

微软开源GraphRAG的使用教程-使用自定义数据测试GraphRAG

微软在今年4月份的时候提出了GraphRAG的概念&#xff0c;然后在上周开源了GraphRAG,Github链接见https://github.com/microsoft/graphrag,截止当前&#xff0c;已有6900Star。 安装教程 官方推荐使用Python3.10-3.12版本&#xff0c;我使用Python3.10版本安装时&#xff0c;在…

Java:String 类

文章目录 一、概念二、创建字符串三、字符串长度四、连接字符串五、比较字符串 一、概念 字符串广泛应用 在 Java 编程中&#xff0c;在 Java 中字符串属于对象&#xff0c;Java 提供了 String 类来创建和操作字符串。 二、创建字符串 创建字符串最简单的方式如下: // 直接创…

利用Python进行数据分析PDF下载经典数据分享推荐

本书由Python pandas项目创始人Wes McKinney亲笔撰写&#xff0c;详细介绍利用Python进行操作、处理、清洗和规整数据等方面的具体细节和基本要点。第2版针对Python 3.6进行全面修订和更新&#xff0c;涵盖新版的pandas、NumPy、IPython和Jupyter&#xff0c;并增加大量实际案例…

什么是Common Flash Interface

目录 1. CFI概述 2. CFI的使用小结 3. CFI在车规MCU里有用吗 在看关于ifx的标准flash驱动配置时&#xff0c;无意中瞄到一个注灰的选项&#xff1a; Try to use CFI information to detect Flash Type 之前讲过CFI这个标准&#xff0c;但为何在IFX memtool工具里注灰&#x…

opencv实现人脸检测功能----20240704

opencv实现人脸检测 早在 2017 年 8 月,OpenCV 3.3 正式发布,带来了高度改进的“深度神经网络”(dnn)模块。 该模块支持多种深度学习框架,包括 Caffe、TensorFlow 和 Torch/PyTorch。OpenCV 的官方版本中包含了一个更准确、基于深度学习的人脸检测器, 链接:基于深度学习…

基于springboot+vue+uniapp的贵工程寝室快修小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

人员定位系统的功能,你知道多少呢?

在此前的文章中&#xff0c;说到了人员定位系统用于化工厂定位这一用途来完善工厂管理&#xff0c;但同时&#xff0c;基于人员定位系统的强大功能&#xff0c;该系统的应用范围也要宽范的多&#xff0c;那么&#xff0c;本篇文章就来为大家介绍一下吧。 人员定位系统的功能简介…

maxwell启动报错:Could not find first log file name in binary log index file

出现该问题是因为&#xff1a;maxwell 读取的是 mysql 的 binlog 日志&#xff0c;而配置文件中的两个值与 binlog 的最新值没有保持一致导致 1. 切换到maxwell的库 show master status;记住图片中的 FIle 和 Position 2. 修改maxwell的配置 SELECT * from positions p ;将…