8

カスタム スキームに従って、クロス タブで動的列を並べ替えようとしています。

ドキュメントで、 comparatorExpression: Crosstab グループ バケット コンパレーター式についての言及を見つけました。この式の結果は、バケットを昇順または降順でソートするために使用されます。比較式が指定されていない場合は、自然順序が使用されます。

しかし、私は表現がどのように見えるべきか理解していません。どうにかして通常のJavaコンパレータを使用できますか? 誰かが例を共有できますか?

4

3 に答える 3

7

もっと簡単で簡単な解決策があるかもしれません:

Jasper Reports Studio (Eclipse プラグイン) を使用しています。

  1. 最終的には機能しませんでした:-( ... (私の回答の下の1.コメントを参照してください-バグの可能性があります) [x] Data Pre Sorted in the Crosstab Propertiesを確認できます。もちろん、これはそうでない場合にのみ機能します事前にソートされた結果セットに基づいて、レポート内の別の場所で別の順序付けが必要です。

  2. 表示のクロス集計グループ ヘッダーを使用しますが、これはかなりトリッキーです。

    1. 新しい行/列グループを作成します(たとえば、アウトライン ビューを使用)。最初の名前Row Group1などはそのままにしておきます。
    2. に設定しTotal PositionますNone(行/列ごとに合計列を生成したくありません)
    3. XML 内のグループを古い​​グループの前に移動します
    4. グループの名前を何か話しやすい名前に変更します。name="invisible sort column ..."
      • (このグループへのこれ以上の参照は XML に存在しないはずです)
    5. グループでグループ合計を使用している場合( Total Position!=None )、基本的にこれらの合計要素/設定を最初のダミーのソート グループに移動する必要があります。列/行のグループ化、例 (ここでは列グループのみを示していますが、行グループも同じ原則に従います)

      a|b|c|sum      a|sum|b|sum|c|sum
      =========  =>  =================
      1|2|3|6        1|1  |2|2  |3|3
      
      • totalPosition=...最も簡単なのは、この変換と同様に XML でこれを行うことです (シナリオに該当する場合は、属性とcolumnTotalGroup=...属性を移動し、合計を変更することを忘れないでください$V{SomeSum_..._ALL})。

        ...
        <columnGroup name="OrderXDummy" height="0">
          ...
          <crosstabTotalColumnHeader>
            <cellContents/>
          </crosstabTotalColumnHeader>
        </columnGroup>
        ...
        <columnGroup name="X" ... totalPosition="End">
          ...
          <crosstabTotalColumnHeader>
            <cellContents ...>
              ...
            </cellContents>
          </crosstabTotalColumnHeader>
        </columnGroup>
        ...
        <crosstabCell ... columnTotalGroup="X">
          ...
           <textFieldExpression><![CDATA[$V{SomeSum_X_ALL}]]></textFieldExpression>
          ...
        </crosstabCell>
        

        =>

        ...
        <columnGroup name="OrderXDummy" height="0" totalPosition="End">
          ...
          <crosstabTotalColumnHeader>
            <cellContents ...>
              ...
            </cellContents>
          </crosstabTotalColumnHeader>
        </columnGroup>
        ...
        <columnGroup name="X" ... >
          ...
          <crosstabTotalColumnHeader>
            <cellContents/>
          </crosstabTotalColumnHeader>
          ...
        </columnGroup>
        ...
        <crosstabCell ... columnTotalGroup="OrderXDummy">
          ...
           <textFieldExpression><![CDATA[$V{SomeSum_OrderXDummy_ALL}]]></textFieldExpression>
          ...
        </crosstabCell>
        
    6. (スキップされる場合があります:)不要に生成された<crosstabCell ... column/rowTotalGroup="...">セルを削除します

      • レポートを以前のバージョンと比較して、XML 内のこれらのスポットを確実かつ迅速に特定することをお勧めします。
      • これは重要なステップではないかもしれませんが、既存の XML を見るとかなり混乱します ;-)
    7. ソート列の(バケット)式を追加ます$F{ORDER_FOR_X}
      • Value Class Nameここで値に割り当てることを忘れないjava.lang.Integerでください(いくつかの列を介して使用している場合は、そこに割り当てられているデータセットを見てください)
    8. 元のグループの に変数式を追加します。Order By Expression$V{ORDER_FOR_X}

      • $V{...}$F{...}はトリックです。使用しないでください。
      • (編集者は無効だと言っていますが、動作します)
      • つまり、並べ替えを定義し、並べ替え対象の列の値に関連するフィールドを提供できる場合、たとえば (Oracle SQL)

        select            1 as order_for_x,  'foo' as x,  'bla blu' as y  from dual
        union all select  2,                 'bar',       'ta tu'         from dual
        union all select  2,                 'bar',       'na na'         from dual
        union all select  1,                 'foo',       'check it'      from dual
        union all select  3,                 'queue',     'sap'           from dual
        
      • それ以外の場合は、もちろんここで他のものを使用することもできます

      • あなたがいくつかを得る必要がある場合

        ...
        Caused by: java.lang.NullPointerException
        at org.apache.commons.collections.comparators.ComparableComparator.compare(ComparableComparator.java:92)
        at net.sf.jasperreports.crosstabs.fill.BucketExpressionOrderer.compareOrderValues(BucketExpressionOrderer.java:70)
        ...
        

        $V{ORDER_FOR_X} == null ? 0 : $V{ORDER_FOR_X}トリックを実行する式を簡単に変更できます

    9. ダミー グループのすべての高/幅フィールドを に設定し0テキストフィールドPrint When Expressionを に設定します。false

    10. (他の何かを台無しにしていないことを確認するために、他に何も変更されていないことを以前のレポート バージョンと比較して確認してください)
  3. メジャーの合計に基づく順序を使用する(下部のリンクで説明されているように)

  4. カスタム Java Comparator クラスを使用する( Pieter VN 2011-11-16からの回答で説明されているように)

私が見つけたさらに役立つリンク:

于 2013-11-22T09:31:18.990 に答える
6

私は同じ問題を抱えており、例や説明は見つかりませんでしたが、その方法を見つけました。説明しますので、他の人がこのソリューションを使用できることを願っています。

以下のコードは jasperreports 3.1.0 と iReport 3.1.4 で使用しましたが、ほぼすべてのバージョンで機能すると思います。

まず、行/列グループのバケット式にどのクラスがあるかを確認する必要があります。デフォルトではこれは java.lang.String ですが、そこにカスタム クラスがあります。これを機能させるには、列グループの xml を次のように編集する必要がありました。

<bucketExpression class="java.lang.String"><![CDATA[$F{customObj}]]></bucketExpression>

<bucketExpression class="com.project.CustomObj"><![CDATA[$F{customObj}]]></bucketExpression>

明らかに、この customObj 値は、レポート自体で定義された、対応するクラスを持つフィールドです。

次に、 Comparator をパラメーターとして追加する必要があります。次に例を示します。

parameters.put("OVERRIDE_Comparator", new Comparator<CustomObj>() {
    public int compare(CustomObj c1, CustomObj c2) {
        //create your custom compare logic over here, this code works as if no custom Comparator is used
        return c1.compareTo(c2);
    }
});

java.util.Comparator パラメータ クラスを使用して、このような OVERRIDE_Comparator パラメータを jasperreport に追加します。

最終ステップ: $P{OVERRIDE_Comparator} を Comparator Expression として、必要な行/列グループに配置します。

このようなレポートをコンパイルする場合、最も可能性の高いコンパイル エラーはキャストの問題です。Jasperreports のデフォルトは java.lang.String です。レポートの xml を手動で編集して、各ステップで正しいクラスを取得する必要がある場合があります。

(私はアジアのサイトからこのメソッドを見つけました。ありがたいことに、コード自体は読み取り可能でした!:-))

于 2011-11-16T14:27:09.807 に答える