SoFunction
Updated on 2025-04-12

Java POI-TL Set Word Pictures to Float above the Text

Requirement description

Insert the image when word exports, and the image floats above the text instead of embedded

poi-tl native insertion picture

poi-tl renders the picture, using the addPicture method, there is a piece of code in this method: CTInline inline = (); means that the image is converted to inline type by default, that is, the element in the line

Solution Custom image rendering plug-in

1. Customize MyPictureRenderPolicy

import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import .;
import .;
import .;

import ;
import ;
import ;
import ;

/**
  * Custom image rendering
  */
public class MyPictureRenderPolicy extends AbstractRenderPolicy<Object> {

    @Override
    protected boolean validate(Object data) {
        if (null == data) {
            return false;
        } else if (data instanceof PictureRenderData) {
            return null != ((PictureRenderData) data).getPictureSupplier();
        } else {
            return true;
        }
    }

    @Override
    public void doRender(RenderContext<Object> context) throws Exception {
        ((), wrapper(()));
    }

    @Override
    protected void afterRender(RenderContext<Object> context) {
        (context, false);
    }

    @Override
    protected void reThrowException(RenderContext<Object> context, Exception e) {
        ("Render picture " + () + " error: {}", ());
        String alt = "";
        if (() instanceof PictureRenderData) {
            alt = ((PictureRenderData) ()).getAltMeta();
        }

        ().setText(alt, 0);
    }

    private static PictureRenderData wrapper(Object object) {
        return object instanceof PictureRenderData ? (PictureRenderData) object : (()).fitSize().create();
    }


    public static class Helper {
        public static void renderPicture(XWPFRun run, PictureRenderData picture) throws Exception {
            Supplier<byte[]> supplier = ();
            byte[] imageBytes = (byte[]) ();
            if (null == imageBytes) {
                throw new IllegalStateException("Can't read picture byte arrays!");
            } else {
                PictureType pictureType = ();
                if (null == pictureType) {
                    pictureType = (imageBytes);
                }

                if (null == pictureType) {
                    throw new RenderException("PictureRenderData must set picture type!");
                } else {
                    PictureStyle style = ();
                    if (null == style) {
                        style = new PictureStyle();
                    }

                    int width = ();
                    int height = ();
                    if (pictureType == ) {
                        imageBytes = (imageBytes, (float) width, (float) height);
                        pictureType = ;
                    }

                    if (!isSetSize(style)) {
                        BufferedImage original = (imageBytes);
                        width = ();
                        height = ();
                        if (() == ) {
                            BodyContainer bodyContainer = (((IBodyElement) ()).getBody());
                            int pageWidth = UnitUtils.twips2Pixel(((IBodyElement) ()));
                            if (width > pageWidth) {
                                double ratio = (double) pageWidth / (double) width;
                                width = pageWidth;
                                height = (int) ((double) height * ratio);
                            }
                        }
                    }

                    InputStream stream = new ByteArrayInputStream(imageBytes);
                    Throwable var25 = null;

                    try {
                         align = ();
                        if (null != align && () instanceof XWPFParagraph) {
                            ((XWPFParagraph) ()).setAlignment((() + 1));
                        }
                        (stream, (), "Generated", (width), (height));
                        //XWPFRunWrapper wrapper = new XWPFRunWrapper(run, false);


                        CTDrawing drawing = ().getDrawingArray(0);
                        CTGraphicalObject graphicalobject = (0).getGraphic();
                        //Get the newly inserted image and add CTAnchor. Set floating attributes. Delete the inline attributes.                        CTAnchor anchor = getAnchorWithGraphic(graphicalobject, "Generated",
                                (width), (height),//Picture size                                (270), (-70), false);//Relative to the current paragraph position, the left offset of the existing content of the paragraph needs to be calculated.
                        (new CTAnchor[]{anchor});//Add floating attribute                        (0);//Delete the in-line attribute                    } catch (Throwable var20) {
                        var25 = var20;
                        throw var20;
                    } finally {
                        if (stream != null) {
                            if (var25 != null) {
                                try {
                                    ();
                                } catch (Throwable var19) {
                                    (var19);
                                }
                            } else {
                                ();
                            }
                        }

                    }

                }
            }
        }

    }

    private static boolean isSetSize(PictureStyle style) {
        return (() != 0 || () != 0) && () == ;
    }

    /**
      * @param ctGraphicalObject Image Data
      * @param deskFileName Image description
      * @param width
      * @param height
      * @param leftOffset Horizontal offset left
      * @param topOffset vertical offset top
      * @param behind above the text, below the text
      * @return
      * @throws Exception
      */
    public static CTAnchor getAnchorWithGraphic(CTGraphicalObject ctGraphicalObject,
                                                String deskFileName, int width, int height,
                                                int leftOffset, int topOffset, boolean behind) {
        String anchorXML =
                "<wp:anchor  xmlns:wp=\"/drawingml/2006/wordprocessingDrawing\" "
                        + "simplePos=\"0\" relativeHeight=\"0\" behindDoc=\"" + ((behind) ? 1 : 0) + "\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"
                        + "<wp:simplePos x=\"0\" y=\"0\"/>"
                        + "<wp:positionH relativeFrom=\"column\">"
                        + "<wp:posOffset>" + leftOffset + "</wp:posOffset>"
                        + "</wp:positionH>"
                        + "<wp:positionV relativeFrom=\"paragraph\">"
                        + "<wp:posOffset>" + topOffset + "</wp:posOffset>" +
                        "</wp:positionV>"
                        + "<wp:extent cx=\"" + width + "\" cy=\"" + height + "\"/>"
                        + "<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>"
                        + "<wp:wrapNone/>"
                        + "<wp:docPr id=\"1\" name=\"Drawing 0\" descr=\"" + deskFileName + "\"/><wp:cNvGraphicFramePr/>"
                        + "</wp:anchor>";


        CTDrawing drawing = null;
        try {
            drawing = (anchorXML);
        } catch (XmlException e) {
            ();
        }
        CTAnchor anchor = (0);
        (ctGraphicalObject);
        return anchor;
    }

}

2. Test

This content automatically adds the image to the end of the word

import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

import ;
import ;
import ;
import ;
import ;
import ;
import ;


/**
  * Data processing - add pictures at the end of the document
  *
  * @author:
  * @date:
  * @description:
  */
public class PoiWordTest3 {

    public static void main(String[] args) throws IOException {
        //The data to be written to the template        Map<String, Object> exampleData = new HashMap<>();


        ("image1", ("src/main/resources/").size(120, 120).create());


        FileInputStream inputStream = new FileInputStream("src/main/resources/");
        XWPFDocument doc = new XWPFDocument(inputStream);
        List<XWPFParagraph> docParagraphs = ();
        if ((docParagraphs)) {
            //The last paragraph            XWPFParagraph paragraph = (() - 1);
            XWPFRun run = ();

            ("{{%image1}} "); //poi-tl required template
        } else {
            //Add paragraph            XWPFParagraph paragraph = ();
            XWPFRun run = ();

            ("{{%image1}} "); //poi-tl required template        }


        // Used to process word files and upload        File tempFileUpload = null;  //Upload temporary files        FileOutputStream tempFileOutputStreamUpload = null; //Upload temporary file output stream        FileInputStream tempFileInputStreamUpload = null; //Upload temporary file input stream        //Temporary file output stream        tempFileUpload = ("wordTempUpload", ".docx");
        tempFileOutputStreamUpload = new FileOutputStream(tempFileUpload);
        (tempFileOutputStreamUpload);
        tempFileInputStreamUpload = new FileInputStream(tempFileUpload);
        /*************************** Register the plugin as a new tag type ******************************************/
        ConfigureBuilder builder = ();
        ('%',new MyPictureRenderPolicy());//Register plugin as new tag type        XWPFTemplate template = (tempFileInputStreamUpload,()).render(exampleData);

        //File output stream        FileOutputStream out = new FileOutputStream("src/main/resources/");
        (out);

        ();
        ();
        ();
    }


}

refer to

Java uses poi-tl to set the word image surround to float above the text

Java poi settings to create a word image as an upper and lower surround and its position

The above is the detailed content of Java POI-TL setting Word pictures floating above the text. For more information about Java POI-TL setting Word pictures, please pay attention to my other related articles!