Как распечатать сноску на странице, содержащей текст?

Я использую textField, которые растягиваются с переполнением и относительно моего textField, я хочу добавить сноску в pageFooter.

Мне нужно напечатать текст в pageFooter, только если страница содержит мой textField или, по крайней мере, сделать так, чтобы нижний колонтитул отображался, когда страница содержит его.

Пример:

У меня есть раздел в моем.jrxml под названием "Witnesseth" и "Section A", например:

Теперь это свидетельство может быть настолько длинным, что его можно переместить на следующую страницу из-за его длины.

У меня есть нижний колонтитул со сноской, как это:

В настоящее время он появляется на каждой странице, но я хочу, чтобы он появлялся только там, где была напечатана часть Раздела А.

1 ответ

Создание сносок в jasper-отчетах имеет две основные проблемы, если вы не хотите публиковать подробный результат (что тоже не просто):

  1. На какой странице textField будет начинаться / заканчиваться при переполнении?

    Только группируя или используя различные полосы детализации, вы можете легко получить информацию о том, на какой странице textField начнет.

  2. pageFooter фиксированный размер (не может масштабироваться динамически)

    Вам необходимо заранее определить пространство, которое будет иметь сноски, в некоторых ограниченных ситуациях вы можете использовать группы groupFooter, которые могут динамически масштабироваться, но эти ситуации ограничены.

Учитывая то, что не существует "окончательного" решения для обработки сносок, я покажу одно, чтобы дать представление о том, что можно сделать в простом сценарии.

Наше ограничение заключается в том, что сноска, относящаяся к textField, будет находиться на странице, на которой начинается textField, кроме того, высота pageFooter допускает максимум 3 сноски на x странице (это мое предопределенное пространство). Обратите внимание, что было бы легко иметь сноску на странице, где заканчиваются textField s, добавив поддельный textField в новую полосу подробностей.

Идея состоит в том, чтобы использовать простой JRScriplet что будет собирать данные, когда printWhenExpression on textField вызывается (он может вызываться несколько раз, поэтому нам нужно это обработать). В pageFooter мы запросим собранные данные для составления нашего списка сносок.

пример

JRScriplet, мы позвоним addFootnote добавить заметку и getFootnoteDatasource распечатать наши текущие сноски.

public class FootnoteScriplet extends JRDefaultScriptlet {

    //Distinct ordered values (since jasper may call more then once)
    private TreeSet<String> footNotes;

    public FootnoteScriplet(){
        super();
        this.footNotes = new TreeSet<>();
    }   

    /**
     * Add a footnote 
     * @param footNote, string of footNote 
     * @return always <code>true</true> since we use in printWhenExpression
     */
    public boolean addFootnote(String footNote){
        this.footNotes.add(footNote);
        return true;
    }

    /**
     * Get the datasource for footNotes and clear for future use.
     * @return
     */
    public JRDataSource getFootnoteDatasource(){
        JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(new ArrayList<>(footNotes));
        this.footNotes.clear();
        return ds;
    }
}

jrxml, запускается с источником данных OnEmptyRecord для тестирования, структура состоит в том, чтобы использовать несколько детализированных полос, вызовите наш сценарий в textField printWhenExpression (которые всегда возвращаются true) добавить сноску, а затем использовать jr:list компонент для отображения собранных сносок в pageFooter,

<?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="Footnotes" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" scriptletClass="my.package.FootnoteScriplet" uuid="b5b15f62-e36a-4c91-a871-ea43faa7d0af">
    <subDataset name="footNoteDS" uuid="884dba42-5c44-4049-a50a-b7e13cc47607">
        <queryString>
            <![CDATA[]]>
        </queryString>
        <field name="_THIS" class="java.lang.String"/>
    </subDataset>
    <parameter name="TEXT" class="java.lang.String">
        <defaultValueExpression><![CDATA["Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"]]></defaultValueExpression>
    </parameter>
    <queryString>
        <![CDATA[]]>
    </queryString>
    <group name="TEXT2" footerPosition="CollateAtBottom">
        <groupExpression><![CDATA["2"]]></groupExpression>
    </group>
    <detail>
        <band height="50">
            <textField isStretchWithOverflow="true">
                <reportElement x="0" y="0" width="550" height="16" isRemoveLineWhenBlank="true" uuid="8def1808-b5c0-45b6-943f-8a88ec04f02b">
                    <printWhenExpression><![CDATA[$P{REPORT_SCRIPTLET}.addFootnote("Footnote 1")]]></printWhenExpression>
                </reportElement>
                <textElement>
                    <font size="12"/>
                </textElement>
                <textFieldExpression><![CDATA["(1)" + $P{TEXT} + "\n" + $P{TEXT}]]></textFieldExpression>
            </textField>
        </band>
        <band height="50">
            <textField isStretchWithOverflow="true">
                <reportElement positionType="Float" x="0" y="0" width="550" height="16" uuid="b6faedf8-11d8-45c8-ac46-e3fb95106140">
                    <printWhenExpression><![CDATA[$P{REPORT_SCRIPTLET}.addFootnote("Footnote 2")]]></printWhenExpression>
                </reportElement>
                <textElement>
                    <font size="12"/>
                </textElement>
                <textFieldExpression><![CDATA["(2)" + $P{TEXT} + "\n" + $P{TEXT}]]></textFieldExpression>
            </textField>
        </band>
        <band height="50">
            <textField isStretchWithOverflow="true">
                <reportElement positionType="Float" x="0" y="0" width="550" height="16" uuid="2db72e84-3e07-4e38-b2bb-c172bbd30956">
                    <printWhenExpression><![CDATA[$P{REPORT_SCRIPTLET}.addFootnote("Footnote 3")]]></printWhenExpression>
                </reportElement>
                <textElement>
                    <font size="12"/>
                </textElement>
                <textFieldExpression><![CDATA["(3)" + $P{TEXT}  + "\n" + $P{TEXT}]]></textFieldExpression>
            </textField>
        </band>
        <band height="50">
            <textField isStretchWithOverflow="true">
                <reportElement positionType="Float" x="0" y="0" width="550" height="16" uuid="4e4b4f2f-4279-4c21-8f0d-62ba92760edd">
                    <printWhenExpression><![CDATA[$P{REPORT_SCRIPTLET}.addFootnote("Footnote 4")]]></printWhenExpression>
                </reportElement>
                <textElement>
                    <font size="12"/>
                </textElement>
                <textFieldExpression><![CDATA["(4)" + $P{TEXT}  + "\n" + $P{TEXT}]]></textFieldExpression>
            </textField>
        </band>
        <band height="50">
            <textField isStretchWithOverflow="true">
                <reportElement positionType="Float" x="0" y="0" width="550" height="16" uuid="5552de59-29f3-49e7-87aa-ee75b811739d">
                    <property name="footNote" value="&quot;FootNote 5&quot;"/>
                    <printWhenExpression><![CDATA[$P{REPORT_SCRIPTLET}.addFootnote("Footnote 5")]]></printWhenExpression>
                </reportElement>
                <textElement>
                    <font size="12"/>
                </textElement>
                <textFieldExpression><![CDATA["(5)"  + $P{TEXT}  + "\n" + $P{TEXT}]]></textFieldExpression>
            </textField>
        </band>
    </detail>
    <pageFooter>
        <band height="64">
            <line>
                <reportElement x="13" y="5" width="534" height="1" uuid="c5b242d5-cafa-43ed-9536-391a4728edf6"/>
                <graphicElement>
                    <pen lineWidth="0.25" lineStyle="Solid"/>
                </graphicElement>
            </line>
            <componentElement>
                <reportElement positionType="Float" x="11" y="10" width="470" height="16" uuid="08bbac11-4f61-4858-8d82-639875dfe1c7"/>
                <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="footNoteDS" uuid="c10d3aaf-8109-4f5b-8099-40450ea9ad7e">
                        <dataSourceExpression><![CDATA[$P{REPORT_SCRIPTLET}.getFootnoteDatasource()]]></dataSourceExpression>
                    </datasetRun>
                    <jr:listContents height="16" width="470">
                        <textField>
                            <reportElement x="0" y="0" width="470" height="16" uuid="d6b5f278-02eb-43d0-934e-5282d37950f5"/>
                            <textElement verticalAlignment="Middle"/>
                            <textFieldExpression><![CDATA[$F{_THIS}]]></textFieldExpression>
                        </textField>
                    </jr:listContents>
                </jr:list>
            </componentElement>
            <textField>
                <reportElement positionType="FixRelativeToBottom" x="500" y="44" width="50" height="20" uuid="7e4a61be-7f67-4003-bd6e-1417cd77378b"/>
                <textElement textAlignment="Right" verticalAlignment="Middle"/>
                <textFieldExpression><![CDATA["P." + $V{PAGE_NUMBER}]]></textFieldExpression>
            </textField>
        </band>
    </pageFooter>
</jasperReport>

Выход

Это далеко от окончательного решения, вместо этого ответ хочет продемонстрировать проблемы, связанные со сносками и дать начальное представление о том, как их решать.

Я исправил свою версию этой проблемы, следуя этому ответу на SO.

Это может быть то, что Петтер упоминает как "метод взлома параметров", но, тем не менее, он следует за страницей, на которой должна находиться сноска, даже если предыдущая страница переполнена и т. Д.

Другие вопросы по тегам