Can JRXML extend data source before using it?

2019-08-16 00:03发布

I use the same data source for generating several reports. One of the reports needs to be printed with a few empty lines ("reserve") at the bottom, so that users can manually write missing data by hand if needed.

E.g.:

+---------+-------------+
| item 1  | bla bla     |
+---------+-------------+
| item 2  | foo         |
+---------+-------------+
|         |             |   <--- here user can just add forgotten
+---------+-------------+        items with a pen
|         |             |
+---------+-------------+

The easiest for the JRXML would be if there were several records of nulls at the end of the data source. Then it would just print its "details" band a few times with no text, just as required. However, the data source is reused for other reports which certainly don't want this.

Can I somehow inject such empty lines into the data source in JRXML itself, just before report filling?

1条回答
贪生不怕死
2楼-- · 2019-08-16 00:34

You can modify your CustomDataSource and set it from jrxml to generate extra records when needed:

Example

public class JRExtraEmptyRecordsDataSource extends JRBeanCollectionDataSource {

    private int nrOfEmptyRecords=0;
    private int currentExtraRecord = 0;

    public JRExtraEmptyRecordsDataSource(Collection<?> beanCollection) {
        super(beanCollection);
    }       

    @Override
    public Object getFieldValue(JRField field) throws JRException {
        if (currentExtraRecord==0){
            return super.getFieldValue(field);
        }
        Class<?> theCorrectClass = field.getValueClass();
        //Implement your logic to return correct class (reflection or switch) if you need speciall values
        //or just return null
        return null;
    }

    @Override
    public boolean next() {
        boolean next = super.next();
        if (next){
            return true;
        }
        currentExtraRecord++;
        return currentExtraRecord<=nrOfEmptyRecords;
    }

    @Override
    public void moveFirst() {
        super.moveFirst();
        currentExtraRecord=0;
    }


    public int getNrOfEmptyRecords() {
        return nrOfEmptyRecords;
    }

    public int setNrOfEmptyRecords(int nrOfEmptyRecords) {
        this.nrOfEmptyRecords = nrOfEmptyRecords;
        return this.nrOfEmptyRecords;//Lets return something for variable
    }

}

When you need extra empty records add this variable definition in your jrxml

<variable name="extraRecords" class="java.lang.Integer">
    <initialValueExpression><![CDATA[((my.package.JRExtraEmptyRecordsDataSource)$P{REPORT_DATA_SOURCE}).setNrOfEmptyRecords(2)]]></initialValueExpression>
</variable>

I do not have custom datasource what can I do?

Normally without custom datasource, you can use the columnFooter with the attribute isFloatColumnFooter="true" (or a dummy group footer band) to display extra info at the end of your detail band. Probably I would choose this method anyway since it helps to customize the extra rows and avoid checking for null in the normal detail band

If you need dynamically to indicate the number of empty records, include a subreport with an empty record and pass as datasource JREmptyDataSource

new net.sf.jasperreports.engine.JREmptyDataSource(P{nrOfEmptyRecords})
查看更多
登录 后发表回答