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

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

 

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

 

安装: docx4j要简单于jacob。docx4j只需要pom文件中添加即可,jacob需要pom添加后在本机jre的bin目录下安装一个dll文件(jacob只支持Windows操作系统)。

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

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

 

一、docx4j的插入操作

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

pom文件:

1

2

3

4

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

 插入图片:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

/**

     * Method Description:使用docx4j插入图片

     *

     * @param templatePath

     *            // 模板文件路径

     * @param targetPath

     *            // 生成的文件路径

     * @param bookmarkName

     *            // 书签名

     * @param imagePath

     *            void // 图片路径

     * @throws Exception

     */

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

    }

 插入文字:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

/**

     * Method Description:使用docx4j插入文字

     *

     * @param templatePath

     *            //模板文件位置

     * @param targetPath

     *            //生成文件位置

     * @param words

     *            //添加的文字内容

     * @param bookmarkName

     *            //书签名称

     * @throws Docx4JException

     * @throws FileNotFoundException

     *

     */

    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

1

2

3

4

5

<dependency>

     <groupId>com.jacob</groupId>

     <artifactId>jacob</artifactId>

     <version>1.18</version>

 </dependency>

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

插入图片:

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

/**

     * Method Description:使用jacob插入图片

     *

     * @param templatePath

     *            //模板文件位置

     * @param targetPath

     *            //生成文件位置

     * @param word

     *            // 查询文字的地方

     * @param imagePath

     *            void // 图片路径

     *

     */

    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[] {});

    }

 

插入文字:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

/**

     * Method Description:使用jacob插入文字

     *

     * @param templatePath

     *            //模板文件位置

     * @param targetPath

     *            //生成文件位置

     * @param words

     *            //要插入的内容

     * @param bookmarkName

     *            void // 书签名

     *

     */

    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[] {});

    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值