# Useful Expressions for Reports and Labels

**URL:** <https://speciforum.org/t/useful-expressions-for-reports-and-labels/384>\
**Category:** Labels & Reports\
**Tags:** Specify-7, Specify-6, Members-only\
**Created:** [June 21, 2025, 5:00am UTC](https://speciforum.org/t/useful-expressions-for-reports-and-labels/384 "2025-06-21T05:00:00Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Grant](https://yyz1.discourse-cdn.com/flex029/user_avatar/speciforum.org/grant/32/4255_2.png) [@Grant](https://speciforum.org/u/Grant)\
**Post date:** [June 21, 2025, 5:00am UTC](https://speciforum.org/t/useful-expressions-for-reports-and-labels/384/1 "2025-06-21T05:00:00Z")

</div>

> 📖 This guide describes several useful or common expressions for altering the appearance of fields in reports and labels.
> 
> :reports_: This guide is intended for collections or IT staff responsible for creating or updating a report or label.

# Useful Expressions

> [!info] What is an expression?  
> All formulas in JasperReports are defined through **expressions**. The default expression language is Java.
> 
> An expression is a formula that operates on some values and returns a result, like a formula in a spreadsheet cell. A cell can have a simple value or a complex formula that refers to other values. In a spreadsheet, you refer to values contained in other cells; in JasperReports you use the report fields, parameters, and variables. Whatever is in your expression, when it is computed, it returns a value (which can be null).
> 
> **Source:** [_Expressions_ – Jaspersoft Studio User Guide](https://community.jaspersoft.com/documentation/jaspersoft%C2%AE-studio/tibco-jaspersoft-studio-user-guide/v900/jss-user-_-expressions-_-expressions/)

This doc contains several common Jaspersoft Studio / iReport expressions, each shown “without” and “with” custom Java-based formatting. After each “with” example is a brief breakdown of how it works. If you have any questions or requests, please leave it as a reply below!

* * *

## Trim Leading Zeros

### Without Expression

 ![Catalog Number with leading zeros](https://canada1.discourse-cdn.com/flex029/uploads/specifysoftware/original/2X/c/c0c246d4541a9d02e9c9b7469cc20e7b4783852a.png)

```java
$F{1.collectionobject.catalogNumber}

```

Example:

- Field value: `000000489`
- Displayed: `000000489`

### With Expression

 ![Catalog Number without leading zeros](https://canada1.discourse-cdn.com/flex029/uploads/specifysoftware/original/2X/b/b02177401fbc7af001fdd9450aa1ce73cc3b4c3d.png)

```java
$F{1.collectionobject.catalogNumber} == null
|| $F{1.collectionobject.catalogNumber}.trim().isEmpty()
  ? ""
  : String.valueOf(
      Integer.parseInt(
        $F{1.collectionobject.catalogNumber}.trim()
      )
    )

```

Example:

- Field value: `000000489`
- Displayed: `489`

#### Breakdown

- First check if there is a catalog number to determine if it should be parsed.
- Treat field as text → parse to number (drops zeros) → back to text.

* * *

## Trim Trailing Zeros

### Without Expression

```java
$F{2.locality.minElevation}

```

Example:

- Field value: `"123.45000"`
- Displayed: `123.45000`

### With Expression

```java
$F{2.locality.minElevation}== null
  ? ""
  : $F{2.locality.minElevation}
      .stripTrailingZeros()
      .toPlainString()

```

Example:

- Field value: `"123.45000"` → parse→ `"123.45"`
- Field value: `"100.0"` → parse→ `"100.0"` → drop “.0” → `100`

#### Breakdown

- If blank, show nothing.
- Else parse → trims zeros → remove “.0” suffix if present.

* * *

## Display Full Month Names

### Cataloged Date

#### Without Expression

```java
$F{…Day} + "-" + $F{…Month} + "-" + $F{…Year}

```

Example:

- Day: `5`, Month: `3`, Year: `2025` → `5-3-2025`

#### With Expression

```java
(
  $F{1.collectionobject.catalogedDateNumericDay} == null 
    ? "" 
    : $F{1.collectionobject.catalogedDateNumericDay} + " "
)
+
(
  $F{1.collectionobject.catalogedDateNumericMonth} == null 
    ? "" 
    : $F{1.collectionobject.catalogedDateNumericMonth} + " "
)
  .replace("10","October")
  .replace("11","November")
  .replace("12","December")
  .replace("1","January")
  .replace("2","February")
  .replace("3","March")
  .replace("4","April")
  .replace("5","May")
  .replace("6","June")
  .replace("7","July")
  .replace("8","August")
  .replace("9","September")
+
(
  $F{1.collectionobject.catalogedDateNumericYear} == null 
    ? "" 
    : $F{1.collectionobject.catalogedDateNumericYear}.toString()
)

```

Example:

- Day: `5`, Month: `3`, Year: `2025` →  
`5 March 2025`

#### Breakdown

- Skip missing parts.
- Add newline after day & month.
- Swap month number for name.
- Append year.

* * *

### Determined Date

#### Without Expression

```java
$F{…Month}

```

Example:

- Month: `11` → `11`

#### With Expression

```java
(
  $F{…Day} == null ? "" : $F{…Day} + " "
) +
(
  $F{…Month} == null ? "" : $F{…Month} + " "
)
  .replace("1","January")…replace("12","December")
+
(
  $F{…Year} == null ? "" : $F{…Year}.toString()
)

```

Example:

- Day: `12`, Month: `11`, Year: `2024` → `12 November 2024`

#### Breakdown

- Skip missing parts.
- Add spaces after day & month.
- Convert month to name.
- Append year.

* * *

## Conditional Display (Hide If Empty or Null)

### Without Expression

```html
"<br><b>Cataloguer</b>"

```

Displayed always:  
  
**Cataloguer**

### With Expression

```java
(
  $F{cataloger} == null
  || $F{cataloger}.isEmpty()
    ? ""
    : "<br><b>Cataloguer</b>"
)

```

Examples:

- Field = `"Jane Doe"` → `<br><b>Cataloguer</b>`
- Field = `""` → `` (nothing)

#### Breakdown

- If blank/missing, show nothing; otherwise show the label.

* * *

## Replace Value with Another (Size Abbreviations)

### Without Expression

```java
$F{1.collectionobject.text1}

```

Example:

- Field = `"Medium"` → `Medium`

### With Expression

```java
$F{text1} == null
  ? ""
  : $F{text1}.equals("Extra Small") ? "XS"
  : $F{text1}.equals("Small") ? "S"
  : $F{text1}.equals("Medium") ? "M"
  : $F{text1}.equals("Large") ? "L"
  : $F{text1}.equals("Extra Large") ? "XL"
  : $F{text1}

```

Examples:

- Field = `"Medium"` → `M`
- Field = `"Extra Large"` → `XL`

#### Breakdown

- If blank, show nothing.
- Else map known sizes to abbreviations; otherwise leave text.

* * *

## Remove Trailing Zeroes

### Without Expression

```java
$F{2.locality.maxElevation}

```

Example:

- Field = `"200.0000"` → `200.0000`

### With Expression

```java
String maxRaw = (String)$F{2.locality.maxElevation};
maxRaw == null || maxRaw.isEmpty()
  ? ""
  : new java.math.BigDecimal(maxRaw)
      .stripTrailingZeros()
      .toPlainString()

```

Example:

- Field = `"200.0000"` → `200`
- Field = `"123.45000"` → `123.45`

#### Breakdown

- If blank, show nothing.
- Else use BigDecimal to strip extra zeros → plain text.

# iReport Examples (Specify 6)

> **Specify 6 Expressions**
>
> ## Replace month with a roman numeral
> 
> If you want to replace the month with a roman numeral in iReport, use the following expression:
> 
> ```auto
> "Date: "+($F{Start_Date_(Day)}==null?"":$F{Start_Date_(Day)}+".").toString()+ ($F{Start_Date_(Month)}+".").toString().replace("10","X").replace("11","XI").replace("12","XII").replace("1","I").replace("2","II").replace("3","III").replace("4","IV").replace("5","V").replace("6","VI").replace("7","VII").replace("8","VIII").replace("9","IX")+($F{Start_Date_(Year)}==null?"":$F{Start_Date_(Year)}).toString()
> 
> ```
> 
> ## Making dates display full month names instead of numbers
> 
> ```auto
> ($F{Collection_Date_(Day)}==null?"":$F{Collection_Date_(Day)}+"
> ").toString()+($F{Collection_Date_(Month)}==null?"":$F{Collection_Date_(Month)}+"
> ").toString().replace("10","October").replace("11","November").replace("12","December").replace
> ("1","January").replace("2","February").replace("3","March").replace("4","April").replace("5","May
> ").replace("6","June").replace("7","July").replace("8","August").replace("9","September")
> +($F{Collection_Date_(Year)}==null?"":$F{Collection_Date_(Year)}+"").toString()
> 
> ```
> 
> ## Making dates have extra zeros
> 
> For example, you date looks like this 2012/7/9 and you want it to look like 2012/07/09. Note that  
> the format is year/month/day here, you can switch it around as you wish. Use this expression:
> 
> ```auto
> "Date: " + ($F{Date_(Year)}==null?"":$F{Date_(Year)}+"").toString()
> +($F{Date_(Month)}==null?"":"/"+(($F{Date_(Month)}+"").toString().length() == 2 ?
> ($F{Date_(Month)}+"").toString(): "0" + $F{Date_(Month)}+"")).toString() +
> ($F{Date_(Day)}==null?"":"/" + (($F{Date_(Day)}+"").toString().length() == 2 ?
> ($F{Date_(Day)}+"").toString(): "0" + $F{Date_(Day)}+"")).toString()
> 
> ```
> 
> ## Display date as “Month Day, Year”
> 
> This would display as something like `November 19, 2000`
> 
> ```auto
> ($F{Date_(Month)}==null?"":$F{Date_(Month)}+" ").toString().replace("10","October").replace("11","November").replace("12","December").replace("1","January").replace("2","February").replace("3","March").replace("4","April").replace("5","May").replace("6","June").replace("7","July").replace("8","August").replace("9","September")+($F{Date_(Day)}==null?"":$F{Date_(Day)}+", ").toString()+($F{Date_(Year)}==null?"":$F{Date_(Year)}+" ").toString()
> 
> ```
> 
> * * *
> 
> ## Getting rid of extra punctuation when fields are null
> 
> For example, you don’t want a report to look like ‘South America, Paraguay , , , ‘ if the rest of  
> some of the fields in the middle of the expression are null. To only make extra punctuation or  
> even words show up only when there is information in the field, format like this:
> 
> ```auto
> ($F{Continent}==null?"":$F{Continent})+($F{Country}==null?"":", " +
> $F{Country})+($F{State}==null?"":", " + $F{State})+($F{County}==null?"":", " +
> $F{County})+($F{Locality_Name}==null?"":", " + $F{Locality_Name})+($F{Latitude1}==null?"":",
> " + $F{Latitude1}+"°").toString()+($F{Longitude1}==null?"":", " + $F{Longitude1}+"°").toString()
> Insert your own fields or do whatever you want, but this should work perfectly.
> 
> ```

---

<div class="post-metadata">

**Author:** ![SPalpurina](https://avatars.discourse-cdn.com/v4/letter/s/ac8455/32.png) [@SPalpurina](https://speciforum.org/u/SPalpurina)\
**Post date:** [June 22, 2025, 12:04am UTC](https://speciforum.org/t/useful-expressions-for-reports-and-labels/384/3 "2025-06-22T00:04:05Z")

</div>

Hello,

Thanks for these handy expressions.

I have the following issue though… When I use the [expressions that replaces month with Roman numeral](https://speciforum.org/t/ireport-and-jaspersoft-studio-useful-expressions/384#replace-month-with-a-roman-numeral-1) I get always values for month and day despite that for some entries I have entered only year. Should not for these cases `$F{1,10.collectingevent.startDateNumericDay}==null?` (and consequently, `$F{1,10.collectingevent.startDateNumericMonth}==null?`) be TRUE?  
How to stop values entered only as Year, e.g. 2023, appear as 1-I-2023?

---

<div class="post-metadata">

**Author:** ![Grant](https://yyz1.discourse-cdn.com/flex029/user_avatar/speciforum.org/grant/32/4255_2.png) [@Grant](https://speciforum.org/u/Grant)\
**Post date:** [June 22, 2025, 12:04am UTC](https://speciforum.org/t/useful-expressions-for-reports-and-labels/384/4 "2025-06-22T00:04:05Z")

</div>

Hi @SPalpurina,

Specify 7 shows a value of `1` in both the numeric month and numeric day fields in query results, regardless of the value of the precision, if there is no value for the month and/or day. We have a feature request open to change this behavior: [#4503](https://github.com/specify/specify7/issues/4503)

To workaround this, you can create a Jaspersoft expression that is conditional based on the value of the precision field (make sure to add this field to the query/report before proceeding):

```java
($F{1,10.collectingevent.startDatePrecision}==3 ? 
  $F{1,10.collectingevent.startDateNumericYear}.toString() : 
  ($F{1,10.collectingevent.startDatePrecision}==2 ? 
    ($F{1,10.collectingevent.startDateNumericMonth}==null?"":$F{1,10.collectingevent.startDateNumericMonth}+" ").toString().replace("10","October").replace("11","November").replace("12","December").replace
    ("1","January").replace("2","February").replace("3","March").replace("4","April").replace("5","May").replace("6","June").replace("7","July").replace("8","August").replace("9","September") + $F{1,10.collectingevent.startDateNumericYear}.toString() : 
    ($F{1,10.collectingevent.startDateNumericDay}==null?"":$F{1,10.collectingevent.startDateNumericDay}+" ").toString() + 
    ($F{1,10.collectingevent.startDateNumericMonth}==null?"":$F{1,10.collectingevent.startDateNumericMonth}+" ").toString().replace("10","October").replace("11","November").replace("12","December").replace
    ("1","January").replace("2","February").replace("3","March").replace("4","April").replace("5","May").replace("6","June").replace("7","July").replace("8","August").replace("9","September") + 
    ($F{1,10.collectingevent.startDateNumericYear}==null?"":""+$F{1,10.collectingevent.startDateNumericYear}).toString())
)

```

This field expression formats the start date of a collecting event based on the precision of the date information available.

1. If the `startDatePrecision` is 3 (indicating a full year), it returns the `startDateNumericYear` as a string.
2. If the `startDatePrecision` is 2 (indicating a month and year):
  - If the `startDateNumericMonth` is `null`, it returns an empty string.
  - Otherwise, it replaces the numeric month value with the corresponding month name (e.g., “10” is replaced with “October”) and concatenates it with the `startDateNumericYear`.

3. If the `startDatePrecision` is not 3 or 2 (indicating a day, month, and year):
  - If the `startDateNumericDay` is `null`, it returns an empty string.
  - Otherwise, it concatenates the `startDateNumericDay`, the month name (as in the previous case), and the `startDateNumericYear`.

This expression replaces the month number with the name, but that is not necessary. Let me know if this solution would work for you!

---

<div class="post-metadata">

**Author:** ![SPalpurina](https://avatars.discourse-cdn.com/v4/letter/s/ac8455/32.png) [@SPalpurina](https://speciforum.org/u/SPalpurina)\
**Post date:** [June 22, 2025, 12:04am UTC](https://speciforum.org/t/useful-expressions-for-reports-and-labels/384/5 "2025-06-22T00:04:05Z")

</div>

Thanks, Grant,

Thanks for your very fast solution and apologies for posting mine too late… I realized I could use the `determinedDatePrecisition` and `collectingevent.startDatePrecisition` already yesterday but I forgot to post my solution. I am glad that we arrived almost at the same solution though.

For me, the following code also worked fine. It seems that the only difference between our solutions is that the check for `null` in the date value is at the beginning of the whole data field. My example is with determination data but it is analogous for the starting date of the collecting event:

`($F{1,9-determinations.determination.determinedDate} == null ? "" : "Det. date: " + ($F{1,9-determinations.determination.determinedDatePrecision} == 1 ? ($F{1,9-determinations.determination.determinedDateNumericDay}+".").toString() + ($F{1,9-determinations.determination.determinedDateNumericMonth}+".").toString().replace("10","X").replace("11","XI").replace("12","XII").replace("1","I").replace("2","II").replace("3","III").replace("4","IV").replace("5","V").replace("6","VI").replace("7","VII").replace("8","VIII").replace("9","IX") : ($F{1,9-determinations.determination.determinedDatePrecision} == 2 ? ($F{1,9-determinations.determination.determinedDateNumericMonth}+".").toString().replace("10","X").replace("11","XI").replace("12","XII").replace("1","I").replace("2","II").replace("3","III").replace("4","IV").replace("5","V").replace("6","VI").replace("7","VII").replace("8","VIII").replace("9","IX") : "")) + $F{1,9-determinations.determination.determinedDateNumericYear}.toString())`
