5、docx4j中图片的使用(编程式)

docx4j
placeholder image
admin 发布于:2018-10-14 14:20:19
阅读:loading

基本介绍

关于docx4j中如何使用图片,如果我不讲到在文档中使用图片,未免我所讲述的知识也太肤浅了吧,言归正传,我在这里给文档插入图片围绕编程式和模板式(我自己这么称的,就是想表达利用模板去实现的意思)的,并且重要的是插入图片的方式有也有两种最常用的“嵌入型”和“衬于文字下方”,我认为这两种才是经常被使用到的。

由于之前也是看到有同事在做word报表时,使用到了盖章的图片,这种盖章的图片就是将插入的图片设置“悬浮”的效果,浮动于一些文本之上,达到一种盖上去的效果。由于使用过这种效果,所以在研究如何插入图片并且可以实现衬于文字下方时的时候,这个问题没搞清楚也一直阻碍我往下进行的脚步。我也尝试着使用前文中的草稿的方式进行编程式的解决,后来没有行通,也查阅了许多资料,均无果,后来查看了一下docx4j提供的插入图片的源码,终于找到了线索。。。。。在源码类BinaryPartAbstractImage.java中隐藏着真相(它里面提供的插入图片的实现,是采用xml模板的方式实现的,提供的插入图片为嵌入型的(函数为createImageInline),由于之前查看的浮动式图片的xml文本的属性标签为Anchor,就查看了一下这个图片处理类的源码,发现关于Anchor的几个方法都给注释掉了,于是将取消注释后,进行代码调用测试,后来又更改了代码中的几个位置,最终运行OK,图片也成为了我期待的效果,参考修改的代码截图为:

image.png

对于衬于文字下方和上方方式的具体设置参考如下图(通过新建文档后docx打开方式为解压缩工具后看到的),1和0分半是衬于文字下方和上方的参数设置:

image.png

关于本示例我将采用编程式的方式分半向新建的文档插入3张图片,其中前面两张图片分半为嵌入型的,第三张图片为浮动型的衬于文字下方,参考效果如下图所示:

image.png

参考代码

    package cn.chendd.docx4j.examples;

     

    import java.io.File;

     

    import org.apache.commons.io.FileUtils;

    import org.docx4j.dml.wordprocessingDrawing.Anchor;

    import org.docx4j.dml.wordprocessingDrawing.Inline;

    import org.docx4j.jaxb.Context;

    import org.docx4j.openpackaging.packages.WordprocessingMLPackage;

    import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;

    import org.docx4j.wml.P;

    import org.docx4j.wml.Text;

     

    public class ImageTest {

     

       public static void main(String[] argsthrows Exception {

          String imagePath = ImageTest.class.getResource("/resources/images/desktop.jpg").getPath();

          File image = new File(imagePath);

          WordprocessingMLPackage wordPackage = WordprocessingMLPackage.createPackage();

          //插入图片1---图片格式为嵌入型

          P p1 = newImageInline(wordPackageFileUtils.readFileToByteArray(image), "111111111""22222",

             1001, 1002 , "这是图1desktop.jsp,看图片的嵌入方式");

          wordPackage.getMainDocumentPart().addObject(p1);

          //插入图片2---图片格式为嵌入型

          P p2 = newImageInline(wordPackageFileUtils.readFileToByteArray(new File(image.getParentFile() ,

             "name.png")), """" , 2001, 2002 , "这是图2name.png,看图片的嵌入方式");

          wordPackage.getMainDocumentPart().addObject(p2);

          //插入图片3---图片格式为衬于文字下方

          P p3 = newImageAnchor(wordPackageFileUtils.readFileToByteArray(new File(image.getParentFile() ,

             "name.png")), """" , 2001, 2002 , "这是图3name.png,看图片的嵌入方式");

          wordPackage.getMainDocumentPart().addObject(p3);

         

          String outPath = System.getProperty("user.dir") + "/template/out/编程式图片.docx";

          wordPackage.save(new File(outPath));

       }

     

       /**

        * 摘自github源码示例代码中的 ImageAdd.java

        */

       public static org.docx4j.wml.P newImageInline(

             WordprocessingMLPackage wordMLPackagebyte[] bytes,

             String filenameHint, String altTextint id1int id2 , String text)

             throws Exception {

     

          BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackagebytes);

     

          Inline inline = imagePart.createImageInline(filenameHintaltTextid1id2false);

     

          // Now add the inline in w:p/w:r/w:drawing

          org.docx4j.wml.ObjectFactory factory = Context.getWmlObjectFactory();

          org.docx4j.wml.P p = factory.createP();

          org.docx4j.wml.R run = factory.createR();

          if(text != null){

             Text txt = factory.createText();

             txt.setValue(text);

             run.getContent().add(txt);

          }

          p.getContent().add(run);

          org.docx4j.wml.Drawing drawing = factory.createDrawing();

          run.getContent().add(drawing);

          drawing.getAnchorOrInline().add(inline);

          return p;

     

       }

     

       /**

        * Create image, without specifying width

        */

       public static org.docx4j.wml.P newImageAnchor( WordprocessingMLPackage wordMLPackage,

             byte[] bytes,

             String filenameHint, String altText,

             int id1int id2 , String textthrows Exception {

         

            BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackagebytes);

            Anchor inline = imagePart.createImageAnchor(filenameHintaltTextid1id2false, 100, 200);

            // Now add the inline in w:p/w:r/w:drawing

          org.docx4j.wml.ObjectFactory factory = Context.getWmlObjectFactory();

          org.docx4j.wml.P  p = factory.createP();

          org.docx4j.wml.R  run = factory.createR();

          if(text != null){

             Text txt = factory.createText();

             txt.setValue(text);

             run.getContent().add(txt);

          }

          p.getContent().add(run);

          org.docx4j.wml.Drawing drawing = factory.createDrawing();

          run.getContent().add(drawing);   

          drawing.getAnchorOrInline().add(inline);

         

          return p;

         

       }

      

    }

相关下载

附上上面讲到的修改源码的类的源码,修改后可字节放置在自己项目内,也可以将编译的class文件替换到jar包所在目录中, 相关下载为:

BinaryPartAbstractImage.zip 源码类修改

编程式图片.docx 代码运行生成文件


 点赞


 发表评论

当前回复:作者

 评论列表


留言区