3

私が2つの豆を持っていると仮定します:

  • アワード
  • 従業員

両方をコレクションに追加します。このコレクションに基づいて、 JRBeanCollectionDataSourceを使用してDynamicJasperを使用してレポートを生成したいと思います。

単一のBeanのレポートを生成できますが、別のBeanのコレクションの場合、レポートを作成できません。エラーが発生します。

一度に2つの異なるBeanのレポートを作成することは可能ですか?

このタスクを解決するための代替ソリューションはありますか?

4

2 に答える 2

1

Award与えられた情報では、 と の間に関係がないことを意味しEmployeeます。その場合は、これを処理するカスタム データ ソースを作成できます。完全を期すために、MixedDataSource と呼ばれるカスタム データ ソースとともに、スタブ化された Award と Employee クラスを含めます。(ここにはたくさんのコードがリストされていますが、しばらくの間、私に固執してください)。

Award.java

package test;

public class Award {

    private String shortName;

    private String description;

    public Award(String shortName, String description) {
        super();
        this.shortName = shortName;
        this.description = description;
    }

    public String getShortName() {
        return shortName;
    }

    public void setShortName(String shortName) {
        this.shortName = shortName;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

従業員.java

package test;

public class Employee {

    private String name;

    private String position;

    public Employee(String name, String position) {
        super();
        this.name = name;
        this.position = position;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPosition() {
        return position;
    }

    public void setPosition(String position) {
        this.position = position;
    }

}

MixedDataSource.java

package test;

import java.util.List;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;

@SuppressWarnings("rawtypes")//have to add this because we are not using generics
public class MixedDataSource implements JRDataSource {

    private List rows;
    private int index=0;

    public MixedDataSource(List rows) {
        super();
        this.rows = rows;
    }

    @Override
    public Object getFieldValue(JRField arg0) throws JRException {
        Object obj = rows.get(index);
        if (obj instanceof Award){
            Award row = (Award)obj;
            //now get the field name
            if (arg0.getName().equals("shortName")){
                return row.getShortName();
            } else if(arg0.getName().equals("description")){
                return row.getDescription();
            }
        } else if (obj instanceof Employee){
            Employee row = (Employee)obj;
            if (arg0.getName().equals("name")){
                return row.getName();
            } else if(arg0.getName().equals("position")){
                return row.getPosition();
            }
        }
        //means we don't know what to do with it, so just return null
        return null;
    }

    @Override
    public boolean next() throws JRException {
        //This method is used by jasper to tell us they are moving to the next row.
        //So increment the index and return true if there are still more rows, if not
        //return false
        index = index+1;
        if(index < rows.size()){
            return true;
        }
        return false;
    }

}

これはうまくいきますが、おそらくあなたが望む方法ではありません。私の仮定では、Award と Employee の間に関係があり、何らかのグループ化と順序付けを行いたいと考えています。基本的に、同じ行にAwardandが必要です。Employee賞でグループ化し、従業員をリストすることができます。逆に、従業員ごとにグループ化し、賞を一覧表示することもできます。その場合は、上記のすべてを無視してください。無駄です。

本当に必要なのは、EmployeeAward持っている情報を使用して新しい Bean ( と呼ぶことができます) を作成することです。SQLクエリを使用してこれを行う場合、これは非常に簡単ですが、休止状態のようなものを使用している場合は、もう少し作業が必要になる場合があります。基本的に、すべての賞を与えると言っているだけで、リストが表示されます。後者を実行している場合は、SQL または HSQL (彼らはそれを何と呼んでいるのかと思います) にステップダウンして、手動でクエリを作成する方がおそらく簡単です。

というクラスを作成しますEmployeeAward。これが私のものです:パッケージテスト;

public class EmployeeAward {


    private String employeeName;

    private String employeePosition;

    private String shortName;

    private String description;

    public EmployeeAward(String employeeName, String employeePosition,
            String shortName, String description) {
        super();
        this.employeeName = employeeName;
        this.employeePosition = employeePosition;
        this.shortName = shortName;
        this.description = description;
    }

    public EmployeeAward(Employee employee, Award award) {
        super();
        this.employeeName = employee.getName();
        this.employeePosition = employee.getPosition();
        this.shortName = award.getShortName();
        this.description = award.getDescription();
    }

    public String getEmployeeName() {
        return employeeName;
    }

    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }

    public String getEmployeePosition() {
        return employeePosition;
    }

    public void setEmployeePosition(String employeePosition) {
        this.employeePosition = employeePosition;
    }

    public String getShortName() {
        return shortName;
    }

    public void setShortName(String shortName) {
        this.shortName = shortName;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }


}

何らかの方法でこれらのオブジェクトのリストを作成したのでList<EmployeeAward> emplyeeAwards、そこにインスタンス化されています。このリストの各項目は、レポートの行になります。これが良い部分です。dataSource を作成します。

JRDataSource datasource = new JRBeanCollectionDataSource(employeeAwards);

その後、通常どおりにそれを渡すと、作業は完了です。

最後に、JasperReports を使用して多くの優れた機能を実現できることをお伝えしたいと思いますが、必要以上に複雑にしている人が多いようです。JasperReports は、私がフラット データソースと呼んでいるもの (つまり、リスト内の同じオブジェクト、リスト内の各項目が行など) に似ていることがわかります。それができれば、人生はもっと楽に楽しくなります。

于 2012-08-24T19:59:40.747 に答える
0

これに代わる方法は、 SubReport を使用して MainReport と SubReport に渡すことです。これにより、SubReport を MainReport拡張として設定できます例:List<Award>List<Employee>

メインレポート: |FieldAward1|FieldAward2|FieldAward3|...|YOUR SUBREPORT HERE|

サブレポート: |FieldEmployee1|FieldEmployee3|FieldEmployee3|...

編集:基本的なように思えますが、あるリスト内の各オブジェクトが別のリスト内のそれぞれのオブジェクトと一致するようにリストを並べ替える必要があることを伝えなければなりません。

于 2012-08-23T20:25:41.680 に答える