Domanda

Sto cercando di ordinare le mie colonne dinamiche in una scheda incrociata secondo uno schema personalizzato.

Nei documenti ho trovato menzione di comparatoreespressione:Espressione del comparatore di bucket del gruppo di tabelle incrociate.Il risultato di questa espressione viene utilizzato per ordinare i secchi, in ordine crescente o discendente.Se non viene specificata alcuna espressione di comparatore, verrà utilizzato l'ordine naturale.

ma non capisco come dovrebbe essere l'espressione.Posso in qualche modo utilizzare un normale comparatore Java?Qualcuno può condividere un esempio?

È stato utile?

Soluzione

Ho avuto lo stesso problema e non ho trovato alcun esempio o spiegazione, ma ho trovato come farlo. Mi spiego, quindi speriamo che le altre persone possono utilizzare questa soluzione.

Ho usato il codice qui sotto per JasperReports 3.1.0 e 3.1.4 iReport, ma credo che funziona per praticamente tutte le versioni.

Per prima cosa si dovrà fare in modo che si sa classe Quale avete nell'espressione secchio per il gruppo di riga / colonna. Per impostazione predefinita, questo è java.lang.String, ma ho una classe personalizzata lì. Per questo lavoro avevo bisogno di modificare il codice XML come questo per il mio gruppo di colonne:

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

a

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

Ovviamente questo valore customObj è un campo con classe corrispondente, definita nella relazione stessa.

Quindi è necessario aggiungere un comparatore come parametro, ad esempio:

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);
    }
});

Ora aggiungere un tale parametro OVERRIDE_Comparator nel JasperReport, utilizzando il java.util.Comparator parametro class.

Passo finale:. Mettere $ P {} OVERRIDE_Comparator come l'espressione di confronto nel gruppo riga / colonna avevi bisogno

Quando si compila tale relazione, l'errore più probabile sarebbe compilare problemi colata. JasperReports default java.lang.String, potrebbe essere necessario modificare il codice XML del report manualmente per ottenere la classe corretta ad ogni passo.

(ho scoperto questo metodo da qualche sito asiatico, per fortuna il codice stesso era leggibile! :-))

Altri suggerimenti

Potrebbero esserci soluzioni molto più semplici e dirette:

Sto utilizzando Jasper Reports Studio (plug-in Eclipse).

  1. alla fine non ha funzionato per me :-( ... (vedi 1.commenta sotto la mia risposta - potrebbe essere un bug) puoi semplicemente controllare [x] Dati preordinati nel Proprietà della tabella a campi incrociati.Naturalmente questo funziona solo se non è necessario un altro ordinamento da qualche altra parte nel report in base al set di risultati preordinato.

  2. utilizzando un intestazione di gruppo invisibile della tabella incrociata, il che è piuttosto complicato:

    1. creare un nuovo gruppo di righe/colonne (per esempio.tramite vista Struttura), lasciare il nome iniziale Row Group1 o simile come è per ora
    2. impostare il suo Total Position A None (non vogliamo avere una colonna totale per riga/colonna generata)
    3. sposta il gruppo nell'XML prima di quello vecchio
    4. rinominare il gruppo a qualche nome parlante, per esempio. name="invisible sort column ..."
      • (non dovrebbero più esistere ulteriori riferimenti a questo gruppo nell'XML)
    5. se sei utilizzando i totali del gruppo sul tuo gruppo (Total Position != None) allora devi farlo in pratica sposta questi elementi/impostazioni totali nel primo gruppo di ordinamento fittizio, perché altrimenti i totali non saranno più totali (= totali per il 2° gruppo) visualizzati dopo ogni colonna/riga di gruppo, ad es.(qui mostrato solo con il gruppo di colonne, ma il gruppo di righe segue lo stesso principio)

      a|b|c|sum      a|sum|b|sum|c|sum
      =========  =>  =================
      1|2|3|6        1|1  |2|2  |3|3
      
      • il modo più semplice potrebbe essere farlo nell'XML in modo simile a questa trasformazione (non dimenticare di spostare il file totalPosition=... E columnTotalGroup=... attributi e per modificare la somma se applicabile al tuo scenario $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. (può essere saltato:) rimuovere quelli generati inutilmente <crosstabCell ... column/rowTotalGroup="..."> cellule

      • forse è meglio confrontare il report con una versione precedente per identificare in modo affidabile e veloce questi punti nell'XML
      • forse questo non è un passaggio cruciale, ma guardare l'XML esistente crea già abbastanza confusione ;-)
    7. aggiungere IL (secchio) espressione della tua colonna di ordinamento, per esempio. $F{ORDER_FOR_X}
      • non dimenticare di assegnare Value Class Name A java.lang.Integer o qualunque cosa si adatti ai tuoi valori qui (dai un'occhiata al tuo set di dati quale tipo è assegnato lì se lo stai utilizzando tramite qualche colonna)
    8. aggiungere qualche variabile espressione al Order By Expression del gruppo originale, ad es. $V{ORDER_FOR_X}

      • $V{...} è il trucco, non usarlo $F{...}!
      • (l'editor dice che non è valido, ma funzionerà)
      • ovvero se puoi fornire un campo che definisce l'ordinamento e si riferisce al valore della colonna da ordinare, ad es.(SQL Oracle)

        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
        
      • altrimenti ovviamente puoi usare anche qualcos'altro qui

      • se dovessi prenderne un po'

        ...
        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)
        ...
        

        puoi semplicemente cambiare l'espressione in $V{ORDER_FOR_X} == null ? 0 : $V{ORDER_FOR_X} che dovrebbe fare il trucco

    9. imposta tutti i campi alti/larghezza del gruppo fittizio A 0 e il campi di testo Print When Expression A false

    10. (magari controlla tramite confronto con la versione precedente del rapporto che non sia cambiato nient'altro per assicurarti di non aver sbagliato qualcos'altro)
  3. utilizzando un ordinare in base ai totali delle misure (come descritto nel link in basso)

  4. usare un classe comparatore Java personalizzata (come descritto nella risposta di Pieter VN 2011-11-16)

ulteriori link forse utili che ho trovato:

orderByExpression

Il modo di ordinare colonne campi incrociati è normalmente utilizzando il orderByExpression

  1. Definire una misura per quello che ti piace di ordinare on (un altro campo o ed espressione, utilizzare definizione di classe corretto nel mio caso un Integer)
<measure name="orderByField_measure" class="java.lang.Integer">
     <measureExpression><![CDATA[$F{orderByField}]]></measureExpression>
</measure>
  1. Utilizzare la misura in orderByExpression nel bucket
<columnGroup name="myColumnGroup" height="10">
      <bucket class="java.lang.String">
        <bucketExpression><![CDATA[$F{MyField}]]></bucketExpression>
        <orderByExpression><![CDATA[$V{orderByField_measure}]]></orderByExpression>
    </bucket>
    .....
</columnGroup>

comparatorExpression

comparatore (creare un classe es java. MyCustomComparator che implementa Comparator)

<bucket class="java.lang.String">
    <bucketExpression><![CDATA[$F{MyField}]]></bucketExpression>
    <comparatorExpression><![CDATA[new com.my.package.MyCustomComparator()]]></comparatorExpression>
</bucket>

paragonabile

Se si sta visualizzando il valore da proprio oggetto ($F{MyField} è un oggetto definito dall'utente) semplice è possibile implementare Paragonabile per visualizzare l'ordine che vuoi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top