How to wrap text around an image?

后端 未结 1 1249
不思量自难忘°
不思量自难忘° 2020-12-18 08:11

I\'m trying to wrap my text around an Image.

The structure I need to create is as in the picture bellow:

This is what I have tried

1条回答
  •  借酒劲吻你
    2020-12-18 09:14

    If you use the html component to wrap text around image, not only do you have a problem of pulling the image from the database, the html component also creates an image of the html, hence the content may be resized/clipped depending on text length and settings on html (image) component.

    I would suggest to use two textFields wrapped around the image (see jrxml) and then calculate where the text will break into next field, so you get first part of text in first textField and second part in second textField

    Java code to calculate text's break point

    This code demonstrate how you can use FontMetric to calculate where Jasper Report will break the text depending on the size of your textField (explanation of code is in comments). The code is not perfectly safe on NullPointer (null text) and on non over-flowing text, furthermore it can be optimized but I will leave this to OP

    import java.awt.Font;
    import java.awt.font.FontRenderContext;
    import java.awt.geom.AffineTransform;
    
    public class WrapImage {
    
        /**
         * Get position where string will break
         * @param text, the text
         * @param width, the width of the component
         * @param height, the height of the component
         * @return the position
         */
        public static int getBreakPosition(String text, int width, int height){
            //Start font context
            AffineTransform affinetransform = new AffineTransform();     
            FontRenderContext frc = new FontRenderContext(affinetransform,true,true);     
    
            //Set same font as used in jasper-report
            Font font = new Font("SansSerif", Font.PLAIN, 10);
            //Get height to understand how many lines
            double textheight = font.getStringBounds(text, frc).getHeight();
            int nrLines = (int)Math.floor(height/textheight);
    
            //init variables
            int breakPos = 0;
            int line = 1;
    
            //loop the lines
            while (line<=nrLines){
                //get remaining text
                String textPart = text.substring(breakPos,text.length());
                //get how much text will fit in line
                breakPos += getLineBreakPosition(textPart, width, font, frc)+1;
                line++;
            }
    
            return breakPos;
    
        }
    
        /**
         * Get where a single line will break
         * @param text, the text
         * @param width, width of component
         * @param font, the font used
         * @param frc, the FontRenderContext
         * @return
         */
        protected static int getLineBreakPosition(String text, int width, Font font, FontRenderContext frc){
            int breakPos  = 0;
            String tmpText = text;
            while (font.getStringBounds(tmpText, frc).getWidth()>width){
                //the break position is space
                breakPos = tmpText.lastIndexOf(' ');
                if (breakPos<=0){
                    breakPos = 0;
                    break;
                }
                tmpText = tmpText.substring(0,breakPos);
            }
            return breakPos;
        }
    }
    

    jrxml example using java code

    In this short example, I use a parameter with some arbitrary sample text. The WrapImage class is in class path. I set a variable to the calculated break point. Then use substring on the text to get first part in first textfield, second in second textField To simplify example, I'm using an image from desktop, for how to pull image from database see: Using images stored in database

    
    
        
            
        
        
            
        
        
            <band height="220" splitType="Stretch">
                <image>
                    <reportElement x="10" y="20" width="80" height="80" uuid="6b4bb467-f7fd-4a15-994b-7c1a01b86428"/>
                    <imageExpression><![CDATA["C:\\Users\\pette\\Desktop\\queen_bee.jpg"]]></imageExpression>
                </image>
                <textField>
                    <reportElement x="100" y="0" width="250" height="100" uuid="f4507624-0410-4feb-9dc5-7d3342b882f0"/>
                    <textElement textAlignment="Justified" verticalAlignment="Bottom"/>
                    <textFieldExpression><![CDATA[$P{longText}.substring(0,$V{breakPos}.intValue())]]></textFieldExpression>
                </textField>
                <textField>
                    <reportElement x="0" y="100" width="350" height="120" uuid="8790bbdd-2066-4ceb-9fc9-dad6154df88c"/>
                    <textElement textAlignment="Justified"/>
                    <textFieldExpression><![CDATA[$P{longText}.substring($V{breakPos}.intValue()+1)]]></textFieldExpression>
                </textField>
            </band>
        
    
    

    Output example

    0 讨论(0)
提交回复
热议问题