nyomtatványok kezelése Java-ban

Jasper Report Dev

Jasper Report Dev

Forráskód - Jasper Reports 6.2.2

Hogyan használjuk fel a Jasper Reports library kódját

2016. július 06. - lacimol

Az esetek többségében a Jasper Studio használata a vizuális felületen való kattintgatásban kimerül, de speciális esetekben szükség lehet a forráskód mélyebb ismeretére is. Ilyen eset lehet a listák kezelése kapcsán használandó JsonDataSource osztály kódja vagy a hibakezelés is.

A forráskódot a https://sourceforge.net/projects/jasperreports/files/jasperreports oldalról tölthetjük le, ha kiválasztjuk a szükséges verziót (pl: 6.2.2), majd a "jasperreports-x.x.x-project.zip" elemet választva. A letöltött fájl kicsomagolása után importálhatjuk az Eclipse-be Maven projektként.

A JsonDataSource kódjának részlete:

public class JsonDataSource extends JRAbstractTextDataSource implements JsonData {
...
    @Override
    public Object getFieldValue(JRField jrField) throws JRException {
        if (currentJsonNode == null) {
            return null;
        }
        String expression = jrField.getDescription();
        if (expression == null || expression.length() == 0) {
            expression = jrField.getName();
            if (expression == null || expression.length() == 0) {
                return null;
            }
        }
        Object value = null;
         
        Class<?> valueClass = jrField.getValueClass();
        JsonNode selectedObject = getJsonData(currentJsonNode, expression);
         
        if (Object.class != valueClass) {
            boolean hasValue = selectedObject != null && !selectedObject.isMissingNode() && !selectedObject.isNull();
            if (hasValue) {
                try {
                    if (valueClass.equals(String.class)) {
                        if (selectedObject.isArray()) {
                            value = selectedObject.toString();
                        } else {
                            value = selectedObject.asText();
                        }                      
                    } else if (valueClass.equals(Boolean.class)) {
                        value = selectedObject.booleanValue();                     
                    } else if (Number.class.isAssignableFrom(valueClass)) {
                        value = convertStringValue(selectedObject.asText(), valueClass);               
                    } else if (Date.class.isAssignableFrom(valueClass)) {
                        value = convertStringValue(selectedObject.asText(), valueClass);
                    } else {
                        throw new JRException(EXCEPTION_MESSAGE_KEY_CANNOT_CONVERT_FIELD_TYPE, new Object[] { jrField.getName(),
                                valueClass.getName() });
                    }
                } catch (Exception e) {
                    throw new JRException(EXCEPTION_MESSAGE_KEY_JSON_FIELD_VALUE_NOT_RETRIEVED, new Object[] { jrField.getName(),
                            valueClass.getName() }, e);
                }
            }
        } else {
            value = selectedObject;
        }
         
        return value;
    }
...
}

List helyett ArrayNode

A fenti kódban látszik, hogy a mező visszatérési értéke csak String, Number, Boolean vagy Date lehet. Ha egy lista elemeit szeretnénk visszakapni java.util.List típusként, akkor csalódnunk kell. Ebben az esetben csak java.lang.Object-ként kérhetjük el, de még így sem cast-olhatjuk List-re, hanem csak JsonNode lehet (selectedObject). Látható az is, hogy ha tömböt String-ként kérünk el, akkor azt ugyan visszakapjuk, de már csak String-ként dolgozhatunk vele (["", "", ""]). A tömb elemeinek számát például nem kérdezhetjük le így (csak csűrés-csavarással: replace + Arrays.asList).

Hogyan tudjuk meg egy adott lista elemeinek számát?

A megoldást a kódban továbbugrálva kaphatjuk meg: getJsonData - goDownPathWithAttribute - goDownPath:

protected JsonNode goDownPath(JsonNode rootNode, String simplePath) {
        if(rootNode != null && !rootNode.isMissingNode()) {
            JsonNode result = null;
            if (rootNode.isObject()) {
                result = rootNode.path(simplePath);
            } else if (rootNode.isArray()) {
                result = mapper.createArrayNode();
                for (JsonNode node: rootNode) {
                    JsonNode deeperNode = node.path(simplePath);
                    if (!deeperNode.isMissingNode()) {
                        if (deeperNode.isArray()) {
                            for(JsonNode arrayNode: deeperNode) {
                                ((ArrayNode)result).add(arrayNode);
                            }
                        } else {
                            ((ArrayNode)result).add(deeperNode);
                        }
                    }
                }
            }
            return result;
        }
        return rootNode;
    }

A createArrayNode() visszatérési értéke com.fasterxml.jackson.databind.node.ArrayNode, amelynek már van size() metódusa, így megkaphatjuk az adott lista elemeinek számát is.

Visszatérési érték bővítése List-tel

A fenti getFieldValue() metódust bővíthetjük a következő kódrészlettel:

@Override
public Object getFieldValue(JRField jrField) throws JRException {
    ...    
    if (Object.class != valueClass) {
        boolean hasValue = selectedObject != null && !selectedObject.isMissingNode() && !selectedObject.isNull();
        if (hasValue) {
            try {
                if (valueClass.equals(String.class)) {
                    ...
                } else if (List.class.equals(valueClass)) {
                    List<Object> result = new ArrayList<Object>();
                    if (!selectedObject.isMissingNode() && selectedObject.isArray()) {
                        value = this.convertToList(selectedObject, result);
                    } else {
                        value = result;
                    }
                     
                } ...
            } catch (Exception e) {
                ...
            }
        }
    } ...
     
    return value;
}

A listát összepakoló metódus szöveges elemként teszi be a listaelemeket, függetlenül azok típusától (a jelenlegi cél a lista elemszámának kiderítése). A listába ágyazott mélységi listák felderítését a rekurzivitás biztosítja.

private List<Object> convertToList(JsonNode selectedObject, List<Object> result) {
        for (JsonNode node : selectedObject) {
            if (!node.isMissingNode() && node.isArray()) {
                List<Object> innerResult = new ArrayList<Object>();
                result.add(innerResult);
                this.convertToList(node, innerResult);
            } else {
                // don't care about type
                result.add(node.asText());
            }
        }
        return result;
    }

A módosított kód használata

A maven install után a target mappában találjuk a "jasperreports-6.2.2.jar" fájlt. A Jasper Studio telepített mappájában keressünk rá a "jasperreports*.jar"-ra és a 6.2.2-es verziót tartalmazzó mappában írjuk felül a legenerált jar fájllal az ottani jart (a mappa helye a frissítésektől függ). Ez a fájl nálam a következő helyen található:

..\configuration\org.eclipse.osgi\506\0\.cp\lib\jasperreports-6.2.2-20160505.150232-15.jar

Az $F{issues} mező class property-jét Object-ről java.util.List-re állítjuk. Így, ha egy jármű bejegyzéseinek számára vagyunk kíváncsiak, akkor a korábban használt kifejezés helyett az $V{issueSize} változóban egy egyszerűbbet használhatunk (nem kell a MissingNode miatti feltétel és nem kell cast-olni sem):

1
2
//($F{issues} instanceof ArrayNode) ? ((ArrayNode)$F{issues}).size() : 0;
$F{issues}.size()

A bejegyzés trackback címe:

https://jasperreport.blog.hu/api/trackback/id/8810618

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.

Kommentezéshez lépj be, vagy regisztrálj! ‐ Belépés Facebookkal

süti beállítások módosítása