0

Is there a way to format a number with fixed length adding separator using Anotation? I ALWAYS receive 10 integer positions and 2 decimal, getting a fixed length of 12

The field anotattion I use:

@Field(at=576, length=12, format="###.##")
private BigDecimal impTotal;

There's an example:

Received: 00000000000150
Value expected: 1.50

Im using this to solve it but I think it could slow the proccess:

public BigDecimal getImpTotal() {
        return impTotal.divide(new BigDecimal(100));
    }

1 Answers1

1

As you have noticed, the pattern that you supply doesn't coerce the string into what you expect. You can do it the way you currently do it, but when you have to do the inverse and output the value in the fixed length format, you will then have to multiply by 100 to get the desired output.

It is the best to use a TypeHandler implementation to do all of this for you. I can't comment on the performance of your implementation versus that of a type handler, you will need to benchmark it.

You need to implement the org.beanio.types.TypeHandler interface. See the JavaDoc comments for further explanations

import org.beanio.types.TypeHandler;

public class MyImpTotalTypeHandler implements TypeHandler {

  private static final BigDecimal BIG_DECIMAL_100_2 = new BigDecimal(100).setScale(2, RoundingMode.HALF_UP);
  private static final BigDecimal BIG_DECIMAL_100 = new BigDecimal(100).setScale(0, RoundingMode.HALF_UP);

  /**
   * We are essentially receiving a (Big)Integer that must be converted to a BigDecimal.
   *
   * @see org.beanio.types.TypeHandler#parse(java.lang.String)
   */
  @Override
  public Object parse(final String value) throws TypeConversionException {

    System.out.printf("Parsing value: %s%n", value);
    return new BigDecimal(value).divide(BIG_DECIMAL_100_2);
  }

  /**
   * To output the value from which this BigDecimal was created, we need to multiply the value with 100.
   *
   * {@inheritDoc}
   *
   * @see org.beanio.types.TypeHandler#format(java.lang.Object)
   */
  @Override
  public String format(final Object value) {

    System.out.printf("Formatting value: %s%n", value);
    return value != null ? ((BigDecimal) value).multiply(BIG_DECIMAL_100).toPlainString() : "";
  }

  @Override
  public Class<?> getType() {

    return BigDecimal.class;
  }

}

You must then register your type handler with the StreamBuilder

final StreamBuilder builder = new StreamBuilder(this.getClass().getSimpleName())
    // your set up here
    // add a TypeHandler to handle the implTotal 
    .addTypeHandler("MyImpTotalTypeHandler", BigDecimal.class, new MyImpTotalTypeHandler())

And then reference this type handler on the field where you want it to be used:

@Field(at = 576, length = 12, handlerName = "MyImpTotalTypeHandler")
private BigDecimal impTotal;

You can also look at extending the existing org.beanio.types.BigDecimalTypeHandler, it might not be as simple as your own implementation though.

nicoschl
  • 2,346
  • 1
  • 17
  • 17