首页 > 其他分享 >使用poi向word中插入文字或图片

使用poi向word中插入文字或图片

时间:2024-05-22 11:08:03浏览次数:11  
标签:word org poi 插入 params pdf apache import

参考自

https://blog.csdn.net/weixin_50638065/article/details/133958393

依赖包

最下面的两个包肯定需要的,其他的有几个不需要的,自己试着删一下,用不了这么多

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>4.1.2</version>
</dependency>
<!--poi-tl-->
<dependency>
    <groupId>com.deepoove</groupId>
    <artifactId>poi-tl</artifactId>
    <version>1.12.1</version>
</dependency>
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.20</version>
</dependency>
<dependency>
    <groupId>com.aspose.words</groupId>
    <artifactId>aspose-words-jdk16</artifactId>
    <version>15.8.0.0</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>3.15</version>
</dependency>

word文档格式

  • 我用的是docx格式,文字替换使用的替换符为 美元符号+大括号,中间是传入的参数名;例:

    ${year}年${month}月${day}日 
    
  • 图片的替换方式为使用“word的标签格式‘;操作步骤为:

    • 先鼠标点击想要插入图片的位置;
    • 菜单栏点击--插入--书签--输入书签名--点击添加;OK了,书签名就是图片的替换文本,也就是代码中map的key;

这里使用apache-aspose去除pdf的水印

在resources目录下加入License.xml配置文件

<!--报表打印,去水印-->
<License>
    <Data>
        <Products>
            <Product>Aspose.Total for Java</Product>
            <Product>Aspose.Words for Java</Product>
        </Products>
        <EditionType>Enterprise</EditionType>
        <SubscriptionExpiry>20991231</SubscriptionExpiry>
        <LicenseExpiry>20991231</LicenseExpiry>
        <SerialNumber><!-- 自己百度找吧 --></SerialNumber>
    </Data>
    <Signature>
     <!-- 自己百度找吧 -->
    </Signature>
</License>

word插入文字、图片、转换成pdf的base64

import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import java.util.List;
import java.util.Map;




/**
     * 获取原文件,并将其生成pdf的base64
     * @param map 需要插入的文本  {"text1":"asdf","text2":"233"}  text1和text2就是插入的文本,在word中用 ${text1};
     * @param map1 需要插入的图片 {"pic1":"base64"}  pic1就是插入word中的标签,值是图片的base64
     * @param base64 原docx文件的base64
     * @return
     */
    public static String searchAndReplace(Map<String, Object> map, Map<String, Object> map1, String base64) {
        // 获取原docx文件
        byte[] decodedBytes = Base64.getDecoder().decode(base64.replaceAll("[^A-Za-z0-9+/=]", ""));
        try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(decodedBytes)){
            XWPFDocument document = new XWPFDocument(byteArrayInputStream);
            // 替换文字与图片标签
            replaceInPara1(document, map, map1);
            // 生成pdf的base64
            return docxConvertPdf(document);
//            ByteArrayOutputStream out = new ByteArrayOutputStream();
//            document.write(out);
//            byte[] bytes = out.toByteArray();
//            out.close();
//            return Base64.getEncoder().encodeToString(bytes);
        } catch (Exception e) {
            // XXXXXXX
        }
        return null;

    }
   
   
     /**
     * 替换段落里面的变量
     * @param doc 要替换的文档
     * @param params 参数
     */
    public static void replaceInPara1(XWPFDocument doc, Map<String, Object> params, Map<String, Object> params1) {
        for (XWPFParagraph para : doc.getParagraphs()) {
            replaceInPara(para, params);
        }
        for (XWPFParagraph para : doc.getParagraphs()) {
            replaceInBook(para, params1);
        }
    }
    
    
    
    
    
    /**
     * 替换段落里面的文字
     *
     * @param paragraph   要替换的段落
     * @param params 参数
     */
    private static void replaceInPara(XWPFParagraph paragraph, Map<String, Object> params) {
        List<XWPFRun> runs = paragraph.getRuns();
        for (int i = 0; i < runs.size(); i++) {
            //获取字符
            String text0 = runs.get(i).getText(runs.get(i).getTextPosition());
            if (text0 != null && text0.contains("$")) {
                //包含占位符的字符缓存
                StringBuilder cache = new StringBuilder(text0);
                int endIndex = 0;
                boolean contains = text0.contains("}");
                //同一个run中是否包含占位符
                if (!contains) {
                    int j = i + 1;
                    for (; j < runs.size(); j++) {
                        String text1 = runs.get(j).getText(runs.get(j).getTextPosition());
                        if (text1 == null) {
                            continue;
                        }
                        cache.append(text1);
                        if (text1.contains("}")) {
                            endIndex = j;
                            break;
                        }
                    }
                }
                if (contains || endIndex != 0) {
                    //处理替换
                    String s = cache.toString();
                    for (Map.Entry<String, Object> entry : params.entrySet()) {
                        String k = entry.getKey();
                        String v = entry.getValue().toString();
                        if (s.contains("${" + k + "}")) {
                            String replace = s.replace("${" + k + "}", v);
                            runs.get(i).setText(replace, 0);
                            for (int j = endIndex; j > i; j--) {
                                runs.get(j).setText("", 0);
                            }
                            break;
                        }
                    }
                }
            }
        }
    }




 /**
     * 替换段落里面的图片标签
     *
     * @param paragraph   要替换的段落
     * @param params 参数
     */
    private static void replaceInBook(XWPFParagraph paragraph, Map<String, Object> params) {
        CTP ctp = paragraph.getCTP();
        for (int dwI = 0; dwI < ctp.sizeOfBookmarkStartArray(); dwI++) {
            CTBookmark bookmark = ctp.getBookmarkStartArray(dwI);
            if (!params.containsKey(bookmark.getName())) continue;
            try (InputStream ins = (InputStream) params.get(bookmark.getName())){
                XWPFRun run = paragraph.createRun();
                //bus.png为鼠标在word里选择图片时,图片显示的名字,100,100则为像素单元,根据实际需要的大小进行调整即可。
                run.addPicture(ins, XWPFDocument.PICTURE_TYPE_PNG, "tutu.png,", Units.toEMU(56), Units.toEMU(35));
            } catch (InvalidFormatException | IOException e) {
                // XXXXXX
            }

        }
    }
    
    
    /**
     * docx转换pdf
     */
    public static String docxConvertPdf(XWPFDocument doc){
        // 写入文档到输出流
        try (ByteArrayOutputStream out = new ByteArrayOutputStream();
             ByteArrayOutputStream outPdf = new ByteArrayOutputStream()){
            doc.write(out);
            // 将输出流转换为字节数组
            byte[] docBytes = out.toByteArray();
            // 将字节数组转换为输入流
            try(InputStream inputStream = new ByteArrayInputStream(docBytes)){
                if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
                    log.error("向docx文件中插入图片时失败");
                    BusiExcUtil.dataIsTrueEx(true, "验证License失败!");
                }
                com.aspose.words.Document document = new com.aspose.words.Document(inputStream);
                document.save(outPdf, SaveFormat.PDF);
                byte[] byteArray = outPdf.toByteArray();
                return Base64.getEncoder().encodeToString(byteArray);
            } catch (Exception e) {
                log.error("docx转换pdf时失败", e);
                BusiExcUtil.dataIsTrueEx(true, "docx转换pdf时失败!");
            }
        } catch (IOException e) {
            log.error("docx转换pdf时失败", e);
            BusiExcUtil.dataIsTrueEx(true, "docx转换pdf时失败!");
        }
        return null;
    }


    /**
     * 验证且去除pdf水印
     * @return
     */
    public static boolean getLicense() {
        try (InputStream is = DocxToPdf.class.getClassLoader().getResourceAsStream("License.xml")){
            License license = new License();
            license.setLicense(is);
            return true;
        } catch (Exception e) {
            log.error("验证且去除pdf水印失败", e);
        }
        return false;
    }
   

标签:word,org,poi,插入,params,pdf,apache,import
From: https://www.cnblogs.com/xy20211005/p/18205800

相关文章

  • word替换快捷操作
    Sub替换词语()DimdocAsDocumentDimfindTextAsStringDimreplaceTextAsString'设置第一个要查找和替换的文本findText="机构管理"replaceText="部门管理"'获取当前活动文档Setdoc=ActiveDocument'开始第一个查找和替换......
  • 允许鼠标响应 css,pointer-events: auto; 和 pointer-events: all; 有什么区别,用哪个
    在CSS中,`pointer-events:auto;`和`pointer-events:all;`实际上并不存在`pointer-events:all;`这个值,因此不用考虑哪个更好。正确的用法是`pointer-events:auto;`。###`pointer-events`属性的概述`pointer-events`属性用于控制一个元素是否响应鼠标事件(如点击、悬停......
  • 如何将word文档转成pdf?教你三个简单方法
    在日常的工作和学习中,我们经常使用Word文档来编写报告、论文、简历等各种文档。然而,在某些情况下,为了确保文档的格式和内容的稳定性,或者方便在不同设备或平台上查看,我们可能需要将Word文档转换为PDF文件。本文将为您详细介绍word文档怎么转pdf的几种方法。一、使用MicrosoftWord......
  • SQL Server 触发器利用临时表在外检表插入前插入主键表
    在SQLServer中,你可以使用触发器(trigger)来在插入学生信息之前,根据班级名称在班级表中插入相应的班级记录。这通常涉及到两步:首先,检查班级表中是否已存在相应的班级;如果不存在,则插入;然后,允许插入学生记录。下面是一个示例,展示如何创建这样的触发器:假设你有两个表:Students 和 C......
  • 在SQLServer中使用SQL语句插入数据出现乱码或问号的解决方法
    原文链接:https://www.cnblogs.com/net5x/p/12430808.html错误产生的原因:        出现使用SQL语句插入数据出现乱码或问号是由于数据库属性的排序规则设置不正确.解决方法:方法一:手动修改(设置数据库的排序规则)注意事项:要确定修改的数据库没有被使用,否则会失败!具体步骤......
  • Python 将PowerPoint (PPT/PPTX) 转为HTML
    PPT是传递信息、进行汇报和推广产品的重要工具。然而,有时我们需要将这些精心设计的PPT演示文稿发布到网络上,以便于更广泛的访问和分享。本文将介绍如何使用Python将PowerPoint文档转换为网页友好的HTML格式。包含两个简单示例:Python将PowerPoint文档转为HTML格式Python将指定......
  • 关于 双向不循环列表的创建、插入、删除、遍历、检索、销毁
    双向循环链表公式双向不循环链表代码#include<stdio.h>#include<stdlib.h>#include<string.h>//宏定义一个数据域#defineDATA_LEN60//双向不循环链表的节点定义typedefstructdouble_link_list{//数据域chardata[DATA_LEN];//数据域,存......
  • P5782 [POI2001] 和平委员会
    P5782[POI2001]和平委员会题目链接思路:因为\(u\)和\(v\)矛盾,即\(\lnot(u\landv)\)。转化成\(\lnotu\lor\lnotv\)。那么根据\(2-SAT\)标准处理方式。转化为:\((u\rightarrow\lnotv)\land(v\rightarrow\lnotu)\)。这里有个小技巧:我们将下标-1,这样我......
  • 手写Word2vec算法实现
    1.语料下载:https://dumps.wikimedia.org/zhwiki/latest/zhwiki-latest-pages-articles.xml.bz2【中文维基百科语料】2.语料处理(1)提取数据集的文本下载的数据集无法直接使用,需要提取出文本信息。安装python库:pipinstallnumpypipinstallscipypipinstallgensimp......
  • mysql5.7 报错:[ERROR] InnoDB: Ignoring the redo log due to missing MLOG_CHECKPOIN
    mysql5.7启动报错:2024-05-19T02:02:14.453082Z0[Warning]TIMESTAMPwithimplicitDEFAULTvalueisdeprecated.Pleaseuse--explicit_defaults_for_timestampserveroption(seedocumentationformoredetails).2024-05-19T02:02:14.453139Z0[Note]--secure-file......