• 分别使用docx4j,jacob将文字与图片插入word中书签位置


    项目中需要将一段文字,与人员的签名(图片)插入到上传的word中,上网查询了一下,有许多种方式可以向word中插入文字,发现docx4j与jacob都为比较常见的解决方案,于是就先使用的docx4j进行了文字与图片的插入,在自己开发的机器上docx4j插入文字与图片均成功了,但是在部署到服务器上的时候,使用docx4j插入图片的时候,一直出现一个图片无法插入的bug,没有解决掉,于是就又使用的jacob进行尝试,然后成功了。将两种对word进行操作的工具进行一下总结。

    安装: docx4j要简单于jacob。docx4j只需要pom文件中添加即可,jacob需要pom添加后在本机jre的bin目录下安装一个dll文件。

    代码量:两者使用同一功能的代码量差不多。

    资料:百度下jacob的资料要比docx4j多一些,docx4j英文的资料多一些,在github下也可以找到docx4j。

    一、docx4j的插入操作

    docx4j安装时候,只需要向pom中添加依赖即可。

    pom文件:

    <groupId>org.docx4j</groupId>
        <artifactId>docx4j</artifactId>
        <version>3.3.1</version>
    </dependency>
    

     插入图片:

    /**
         * Method Description:使用docx4j插入图片
         *
         * @param templatePath
         *            // 模板文件路径
         * @param targetPath
         *            // 生成的文件路径
         * @param bookmarkName
         *            // 书签名
         * @param imagePath
         *            void // 图片路径
         * @throws Exception
         * @Author: 张昊亮
         * @Date: 2018年5月17日 下午4:17:20
         */
        public void insertPicture(String templatePath, String targetPath, String bookmarkName, String imagePath) throws Exception {
    
            // 载入模板文件
            WordprocessingMLPackage wPackage = WordprocessingMLPackage.load(new FileInputStream(templatePath));
            // 提取正文
            MainDocumentPart mainDocumentPart = wPackage.getMainDocumentPart();
            Document wmlDoc = (Document) mainDocumentPart.getJaxbElement();
            Body body = wmlDoc.getBody();
            // 提取正文中所有段落
            List<Object> paragraphs = body.getContent();
            // 提取书签并创建书签的游标
            RangeFinder rt = new RangeFinder("CTBookmark", "CTMarkupRange");
            new TraversalUtil(paragraphs, rt);
            // 遍历书签
            for (CTBookmark bm : rt.getStarts()) {
                // 这儿可以对单个书签进行操作,也可以用一个map对所有的书签进行处理
                if (bm.getName().equals(bookmarkName)) {
                    // 读入图片并转化为字节数组,因为docx4j只能字节数组的方式插入图片
                    InputStream is = new FileInputStream(imagePath);
                    byte[] bytes = IOUtils.toByteArray(is);
                    // 创建一个行内图片
                    BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wPackage, bytes);
                    // createImageInline函数的前四个参数我都没有找到具体啥意思
                    // 最有一个是限制图片的宽度,缩放的依据
                    Inline inline = imagePart.createImageInline(null, null, 0, 1, false, 800);
                    // 获取该书签的父级段落
                    P p = (P) (bm.getParent());
                    ObjectFactory factory = new ObjectFactory();
                    // R对象是匿名的复杂类型,然而我并不知道具体啥意思,估计这个要好好去看看ooxml才知道
                    R run = factory.createR();
                    // drawing理解为画布
                    Drawing drawing = factory.createDrawing();
                    drawing.getAnchorOrInline().add(inline);
                    run.getContent().add(drawing);
                    p.getContent().add(run);
                }
            }
            wPackage.save(new FileOutputStream(targetPath));
        }
    

     插入文字:

    /**
         * Method Description:使用docx4j插入文字
         *
         * @param templatePath
         *            //模板文件位置
         * @param targetPath
         *            //生成文件位置
         * @param words
         *            //添加的文字内容
         * @param bookmarkName
         *            //书签名称
         * @throws Docx4JException
         * @throws FileNotFoundException
         *
         * @Author: 张昊亮
         * @Date: 2018年5月21日 上午10:02:51
         */
        public void insertWords(String templatePath, String targetPath, String words, String bookmarkName) throws FileNotFoundException,
                Docx4JException {
    
            // 载入模板文件
            WordprocessingMLPackage wPackage = WordprocessingMLPackage.load(new FileInputStream(templatePath));
            // 提取正文
            MainDocumentPart mainDocumentPart = wPackage.getMainDocumentPart();
            Document wmlDoc = (Document) mainDocumentPart.getJaxbElement();
            Body body = wmlDoc.getBody();
            // 提取正文中所有段落
            List<Object> paragraphs = body.getContent();
            // 提取书签并创建书签的游标
            RangeFinder rt = new RangeFinder("CTBookmark", "CTMarkupRange");
            new TraversalUtil(paragraphs, rt);
            // 遍历书签
            for (CTBookmark bm : rt.getStarts()) {
                // 这儿可以对单个书签进行操作,也可以用一个map对所有的书签进行处理
                if (bm.getName().equals(bookmarkName)) {
                    ObjectFactory factory = new ObjectFactory();
                    P p = (P) (bm.getParent()); // 添加到了标签处
                    R r = factory.createR();
                    Text t = new Text();
                    t.setValue(words);
                    r.getContent().add(t);
                    p.getContent().add(r);
                    wPackage.getMainDocumentPart().getContent().add(p);
                }
            }
            wPackage.save(new FileOutputStream(targetPath));
        }
    

     二、使用jacob进行插入操作

    jacob在安装的时候需要,有jar包还有dll文件。

    jacob包文件下载:链接:https://pan.baidu.com/s/1v0ZYsVYSu_BO5rB252ufvA 密码:mlfs

    <dependency>
         <groupId>com.jacob</groupId>
         <artifactId>jacob</artifactId>
         <version>1.18</version>
     </dependency>
    

     maven项目,添加pom依赖后,需要将jacob-1.18-x64.dll 文件放入项目所在电脑的jre的bin目录下,方可运行。

    插入图片:

    注:图片在资料中没有查询到的在书签位置插入,而是使用的用图片去替换文字。

    /**
         * Method Description:使用jacob插入图片
         *
         * @param templatePath
         *            //模板文件位置
         * @param targetPath
         *            //生成文件位置
         * @param word
         *            // 查询文字的地方
         * @param imagePath
         *            void // 图片路径
         *
         * @Author: 张昊亮
         * @Date: 2018年5月23日 下午4:18:27
         */
        public void insertPicByjacob(String templatePath, String targetPath, String word, String imagePath) {
    
            System.out.println("启动word...");
            ActiveXComponent app = null;
            Dispatch doc = null;
            // 模板的路径
            String openPath = templatePath;
            // 要保存的文件的路径
            String toFileName = targetPath;
            Dispatch docs = null;
            if (app == null || app.m_pDispatch == 0) {
                app = new ActiveXComponent("Word.Application");
                app.setProperty("Visible", new Variant(false));
                app.setProperty("DisplayAlerts", new Variant(false));
            }
            if (docs == null) {
                // 获得documents对象
                docs = app.getProperty("Documents").toDispatch();
            }
            doc = Dispatch.invoke(docs, "Open", Dispatch.Method, new Object[] { openPath, new Variant(false), new Variant(true) }, new int[1])
                    .toDispatch();
            System.out.println("打开文档..." + openPath);
            Dispatch selection = app.getProperty("Selection").toDispatch();
            Dispatch find = Dispatch.call(selection, "Find").toDispatch();// 获得Find组件
            Dispatch.put(find, "Text", word); // 查找字符串
            Dispatch.put(find, "MatchWholeWord", "True"); // 全字匹配
            boolean bl = Dispatch.call(find, "Execute").getBoolean(); // 执行查询
            if (bl) {
                Dispatch inLineShapes = Dispatch.get(selection, "InLineShapes").toDispatch();
                Dispatch picture = Dispatch.call(inLineShapes, "AddPicture", imagePath).toDispatch();
            }
            // 保存文件//new variant() 参数 0Doc 12、16Docx 17pdf
            Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[] { targetPath, new Variant(12) }, new int[1]);
            Dispatch.call((Dispatch) doc, "Close", new Variant(false));
            System.out.println("关闭文档");
            if (app != null)
                app.invoke("Quit", new Variant[] {});
        }
    

    插入文字:

    /**
         * Method Description:使用jacob插入文字
         *
         * @param templatePath
         *            //模板文件位置
         * @param targetPath
         *            //生成文件位置
         * @param words
         *            //要插入的内容
         * @param bookmarkName
         *            void // 书签名
         *
         * @Author: 张昊亮
         * @Date: 2018年5月24日 下午5:15:25
         */
        public void insertWordByjacob(String templatePath, String targetPath, String words, String bookmarkName) {
    
            System.out.println("启动word...");
            ActiveXComponent app = null;
            Dispatch doc = null;
            // 模板的路径
            String openPath = templatePath;
            // 要保存的文件的路径
            String toFileName = targetPath;
            Dispatch docs = null;
            if (app == null || app.m_pDispatch == 0) {
                app = new ActiveXComponent("Word.Application");
                app.setProperty("Visible", new Variant(false));
                app.setProperty("DisplayAlerts", new Variant(false));
            }
            if (docs == null) {
                // 获得documents对象
                docs = app.getProperty("Documents").toDispatch();
            }
            doc = Dispatch.invoke(docs, "Open", Dispatch.Method, new Object[] { openPath, new Variant(false), new Variant(true) }, new int[1])
                    .toDispatch();
            System.out.println("打开文档..." + openPath);
            Dispatch activeDocument = app.getProperty("ActiveDocument").toDispatch();
            Dispatch bookMarks = app.call(activeDocument, "Bookmarks").toDispatch();
            Dispatch rangeItem = Dispatch.call(bookMarks, "Item", bookmarkName).toDispatch();
            Dispatch range = Dispatch.call(rangeItem, "Range").toDispatch();
            Dispatch.put(range, "Text", new Variant(words));
            // 保存文件//new variant() 参数 0Doc 12、16Docx 17pdf
            Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[] { targetPath, new Variant(12) }, new int[1]);
            Dispatch.call((Dispatch) doc, "Close", new Variant(false));
            System.out.println("关闭文档");
            if (app != null)
                app.invoke("Quit", new Variant[] {});
        }
    
  • 相关阅读:
    JS_ ','逗号
    JS_prettyBanner[说给自己听]
    JS_关键字详细
    CSS_圣杯
    JS_ifream通信
    [转]<!DOCTYPE html>
    JS_ImageLazylode[说给自己听]
    CSS_负边距
    JS_waterfall[说给自己听]
    JS_call,apply
  • 原文地址:https://www.cnblogs.com/zhanghaoliang/p/9098508.html
Copyright © 2020-2023  润新知