Java 如何在结束的换行文本字段中的所有行下创建虚线?

Java 如何在结束的换行文本字段中的所有行下创建虚线?,java,jasper-reports,border,Java,Jasper Reports,Border,我正在寻找一种创建jasper报告元素的方法,该元素表示动态高度,并将文本框标记为带有溢出的textField 文本框的内容应包括自始至终每行的虚线 所需结果的草图。 最终决定 public class JRSplitText { private String text; private int firstLineCharacterCount = 0; private AttributedString attributedString; public JRS

我正在寻找一种创建jasper报告元素的方法,该元素表示动态高度,并将文本框标记为带有溢出的
textField

文本框的内容应包括自始至终每行的虚线

所需结果的草图。

最终决定

public class JRSplitText {
    private String text;
    private int firstLineCharacterCount = 0;

    private AttributedString attributedString;

    public JRSplitText(String text, String fontName, int fontStyle, float fontSize) {
        this.text = text;

        FontUtil fontUtil = FontUtil.getInstance(DefaultJasperReportsContext.getInstance());
        Font font = fontUtil.getAwtFontFromBundles(fontName, fontStyle, fontSize, Locale.getDefault(), true);

        attributedString = new AttributedString(text);
        attributedString.addAttribute(TextAttribute.FONT, font);
    }

    public String getText(int wrappingWidth) {
        if(text == null) {
            return null;
        }

        AffineTransform transform = new AffineTransform();
        FontRenderContext frc = new FontRenderContext(transform, true, true);

        AttributedCharacterIterator iterator = attributedString.getIterator();
        LineBreakMeasurer measurer = new LineBreakMeasurer(iterator, frc);

        TextLayout layout = measurer.nextLayout(wrappingWidth);
        firstLineCharacterCount = layout.getCharacterCount();

        return text.substring(0, firstLineCharacterCount);
    }

    public JRDataSource getDataSource(int wrappingWidth) {
        if(text == null) {
            return null;
        }

        List<String> list = new ArrayList<>();

        AffineTransform transform = new AffineTransform();
        FontRenderContext frc = new FontRenderContext(transform, true, true);

        AttributedCharacterIterator iterator = attributedString.getIterator();
        LineBreakMeasurer measurer = new LineBreakMeasurer(iterator, frc);
        measurer.setPosition(firstLineCharacterCount);

        while (measurer.getPosition() < iterator.getEndIndex()) {
            TextLayout layout = measurer.nextLayout(wrappingWidth);
            String line = text.substring(measurer.getPosition() - layout.getCharacterCount(), measurer.getPosition());

            list.add(line);
        }

        if(list.isEmpty()) {
            return null;
        }

        return new JRBeanCollectionDataSource(list);
    }
}
公共类JRSplitText{
私有字符串文本;
private int firstLineCharacterCount=0;
私有AttributeString AttributeString;
公共文本(字符串文本、字符串字体名称、int-fontStyle、float-fontSize){
this.text=文本;
FontUtil FontUtil=FontUtil.getInstance(DefaultJasperReportsContext.getInstance());
Font Font=fontUtil.getAwtFontFromBundles(fontName,fontStyle,fontSize,Locale.getDefault(),true);
attributedString=新的attributedString(文本);
attributedString.addAttribute(TextAttribute.FONT,FONT);
}
公共字符串getText(int wrappingWidth){
if(text==null){
返回null;
}
仿射变换=新仿射变换();
FontRenderContext frc=新的FontRenderContext(变换,真,真);
AttributedCharacterIterator迭代器=attributedString.getIterator();
LineBreakMeasurer measurer=新的LineBreakMeasurer(迭代器,frc);
text布局=measurer.nextLayout(wrappingWidth);
firstLineCharacterCount=layout.getCharacterCount();
返回text.substring(0,firstLineCharacterCount);
}
公共JRDataSource getDataSource(int wrappingWidth){
if(text==null){
返回null;
}
列表=新的ArrayList();
仿射变换=新仿射变换();
FontRenderContext frc=新的FontRenderContext(变换,真,真);
AttributedCharacterIterator迭代器=attributedString.getIterator();
LineBreakMeasurer measurer=新的LineBreakMeasurer(迭代器,frc);
测量器设置位置(firstLineCharacterCount);
while(measurer.getPosition()
并测试jrxml文件

<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.4.0.final using JasperReports Library version 6.4.1  -->
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="Blank_A4_1" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="f9a6be97-9be4-4067-9185-a2a909bd704c">
    <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
    <subDataset name="Dataset1" uuid="ebf3dce1-fb7a-427e-b156-4053fbbdd833">
        <queryString>
            <![CDATA[]]>
        </queryString>
        <field name="_THIS" class="java.lang.String"/>
    </subDataset>
    <parameter name="lorem ipsum" class="java.lang.String"/>
    <parameter name="testParam" class="JRSplitText" isForPrompting="false">
        <parameterDescription><![CDATA[]]></parameterDescription>
        <defaultValueExpression><![CDATA[new JRSplitText($P{lorem ipsum}, "SansSerif", java.awt.Font.BOLD, 10.0f)]]></defaultValueExpression>
    </parameter>
    <queryString>
        <![CDATA[]]>
    </queryString>
    <background>
        <band splitType="Stretch"/>
    </background>
    <columnHeader>
        <band height="16" splitType="Stretch">
            <frame>
                <reportElement x="0" y="0" width="556" height="0" uuid="422c3774-9917-4908-af5d-d695eb4c0af0">
                    <property name="com.jaspersoft.studio.unit.height" value="pixel"/>
                </reportElement>
                <box>
                    <topPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
                    <leftPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
                    <bottomPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
                    <rightPen lineWidth="0.0" lineStyle="Solid" lineColor="#000000"/>
                </box>
                <staticText>
                    <reportElement x="0" y="0" width="100" height="18" uuid="258f51ab-e5f3-4c84-a483-87d03ff4adf7"/>
                    <textElement verticalAlignment="Bottom"/>
                    <text><![CDATA[This is a Label:]]></text>
                </staticText>
                <textField>
                    <reportElement x="100" y="0" width="456" height="18" uuid="aadc75c9-2599-4051-a37d-af3583ec3635"/>
                    <box>
                        <bottomPen lineWidth="1.0" lineStyle="Dotted"/>
                    </box>
                    <textElement verticalAlignment="Bottom">
                        <font fontName="SansSerif" size="10" isBold="true"/>
                        <paragraph leftIndent="2"/>
                    </textElement>
                    <textFieldExpression><![CDATA[$P{testParam}.getText(454)]]></textFieldExpression>
                </textField>
                <staticText>
                    <reportElement x="100" y="18" width="456" height="8" uuid="059e4872-c8f0-44f7-ac32-4e7b42ce1942">
                        <property name="com.jaspersoft.studio.unit.height" value="pixel"/>
                    </reportElement>
                    <textElement textAlignment="Center">
                        <font size="6"/>
                    </textElement>
                    <text><![CDATA[(hint ...)]]></text>
                </staticText>
                <componentElement>
                    <reportElement x="0" y="18" width="556" height="18" isRemoveLineWhenBlank="true" uuid="aaa64777-42be-45ff-8045-9916e75aaf31"/>
                    <jr:list xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd" printOrder="Vertical">
                        <datasetRun subDataset="Dataset1" uuid="5f0160cd-5fef-43e9-970e-fde5226a2aeb">
                            <dataSourceExpression><![CDATA[$P{testParam}.getDataSource(556)]]></dataSourceExpression>
                        </datasetRun>
                        <jr:listContents height="18" width="556">
                            <textField isBlankWhenNull="false">
                                <reportElement x="0" y="0" width="556" height="18" isRemoveLineWhenBlank="true" uuid="f0ba1742-9bae-452c-9e98-3518e0951571">
                                    <property name="com.jaspersoft.studio.unit.height" value="pixel"/>
                                </reportElement>
                                <box>
                                    <bottomPen lineWidth="1.0" lineStyle="Dotted"/>
                                </box>
                                <textElement verticalAlignment="Bottom">
                                    <font isBold="true"/>
                                    <paragraph leftIndent="0"/>
                                </textElement>
                                <textFieldExpression><![CDATA[$F{_THIS}]]></textFieldExpression>
                            </textField>
                        </jr:listContents>
                    </jr:list>
                </componentElement>
            </frame>
            <staticText>
                <reportElement positionType="Float" x="455" y="0" width="100" height="16" forecolor="#857D7D" uuid="8bee13b8-2322-489b-8ab0-2e3c7c6742d1">
                    <property name="com.jaspersoft.studio.unit.y" value="pixel"/>
                </reportElement>
                <textElement textAlignment="Right"/>
                <text><![CDATA[Static Text]]></text>
            </staticText>
        </band>
    </columnHeader>
</jasperReport>


JasperReports中没有可以直接实现这一点的设置,最简单的策略之一可能是将文本转换为数据源,从而生成一个行列表,然后在文本字段中显示每一行,并在其下方加一条虚线

为了创建数据源,我们需要计算何时会发生换行,为此我们需要使用java,我将使用

Java根据
wrappingWidth
Font
将长文本转换为行列表的代码

public class JRSplitText {

    public static JRDataSource getTextDataSource(String text, int wrappingWidth, String fontName, int fontStyle, int fontSize) {
        // Our list with the different text segements (lines)
        List<String> textSegements = new ArrayList<>();

        // Instance a FontRenderContext
        AffineTransform affinetransform = new AffineTransform();
        FontRenderContext frc = new FontRenderContext(affinetransform, true, true);

        // Instance the AttributedString and it's iterator
        AttributedString attrText = new AttributedString(text);
        // To consider font-extensions lets load font directly from jasper-reports
        FontUtil fontUtil = FontUtil.getInstance(DefaultJasperReportsContext.getInstance());
        Font font = fontUtil.getAwtFontFromBundles(fontName, fontStyle, fontSize, Locale.getDefault(), false);
        attrText.addAttribute(TextAttribute.FONT, font);
        AttributedCharacterIterator styledText = attrText.getIterator();

        // Start measurer how much text can fit in our width and add each line
        // to our list
        LineBreakMeasurer measurer = new LineBreakMeasurer(styledText, frc);
        while (measurer.getPosition() < styledText.getEndIndex()) {
            TextLayout layout = measurer.nextLayout(wrappingWidth);
            String line = text.substring(measurer.getPosition() - layout.getCharacterCount(), measurer.getPosition());
            textSegements.add(line);
        }

        // return a datasource of our lists
        return new JRBeanCollectionDataSource(textSegements);
    }
}
输出

虚线在屏幕截图中看起来并不好,但这只是一个屏幕截图问题

注意:
wrappingWidth
和字体参数是
textField
的宽度及其字体。行高由
textField


“不强调标签”这句话的意思是什么?AFIK没有简单的方法来做你需要的事情。方法1)计算行拆分的位置并转换为数据源。方法2)编写自定义渲染。在您将字符串传递给jasper report之前,您是否有可能用java详细阐述您的字符串?是的,我有机会做任何事情。但正如我理解你的想法,我需要访问字符串将在其中绘制的上下文。否则,我看不出如何确定在何处断开字符串。我将在文档中查看创建自定义渲染所需的选项,但我希望有一些指导。我没有看到添加标签(第一行开头的下划线)的方法。但是这个想法变得清晰了,我会尝试开发它。@mrmcwolf对于标签“文本字段标签”,我会添加另一个文本字段,然后
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="lineBreakTest" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="597c0716-df6b-42ec-a7c8-863eb1b7174a">
    <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
    <subDataset name="datasource" uuid="6a442aa1-3bf1-494c-9654-e6d3122dd5a7">
        <queryString>
            <![CDATA[]]>
        </queryString>
        <field name="_THIS" class="java.lang.String"/>
    </subDataset>
    <parameter name="text" class="java.lang.String">
        <defaultValueExpression><![CDATA["Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."]]></defaultValueExpression>
    </parameter>
    <title>
        <band height="18">
            <componentElement>
                <reportElement positionType="Float" x="2" y="0" width="550" height="15" uuid="3a68753d-ac77-4941-9dd9-fdeca5ad2f76"/>
                <jr:list xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd" printOrder="Vertical">
                    <datasetRun subDataset="datasource" uuid="a76bcffd-57ad-44bf-b2c9-20b89089e440">
                        <dataSourceExpression><![CDATA[jdd.so.JRSplitText.getTextDataSource($P{text},550,"SansSerif",java.awt.Font.PLAIN,10)]]></dataSourceExpression>
                    </datasetRun>
                    <jr:listContents height="15" width="550">
                        <textField>
                            <reportElement x="0" y="0" width="550" height="15" uuid="c9685fa5-a942-4709-9fa9-98e9cc80bc5c"/>
                            <box>
                                <bottomPen lineWidth="1.0" lineStyle="Dotted"/>
                            </box>
                            <textElement>
                                <font fontName="SansSerif" size="10"/>
                            </textElement>
                            <textFieldExpression><![CDATA[$F{_THIS}]]></textFieldExpression>
                        </textField>
                    </jr:listContents>
                </jr:list>
            </componentElement>
        </band>
    </title>
</jasperReport>