NumberCell.java
package com.github.mygreen.cellformatter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import com.github.mygreen.cellformatter.lang.ExcelDateUtils;
/**
* 数値型の値を直接扱うための仮想的なセル。
* <p>Javaの数値型のクラスに対応しています。</p>
* <ul>
* <li>プリミティブ型:byte/shrot/int/long/float/double</li>
* <li>ラッパークラス:Byte/Short/Integer/Long/Float/Double</li>
* <li>その他:AtomicInteger/AtomicLong/BigDecimal/BigInteger</li>
* </ul>
*
* @since 0.6
* @param <T> Javaの数値クラス。
* @author T.TSUCHIE
*
*/
public class NumberCell<T extends Number> extends ObjectCell<T> {
/** 日付の始まりが1904年開始かどうか */
private final boolean dateStart1904;
/**
* コンストラクタで渡した値の数値表現。
*/
private double number;
/**
* 値と書式のインデックス番号を指定するコンストラクタ。
* <p>フォーマットの書式は、{@literal null}になります。
* @param value フォーマット対象の値。
* @param formatIndex 書式のインデックス番号。
* @throws IllegalArgumentException {@literal value == null}.
* @throws IllegalArgumentException {@literal formatIndex < 0}
*
*/
public NumberCell(final T value, final short formatIndex) {
this(value, formatIndex, false);
}
/**
* 値とその書式を指定するコンストラクタ。
* <p>フォーマットのインデックス番号は、{@literal 0}となります。
* @param value フォーマット対象の値。
* @param formatPattern Excelの書式。
* @throws IllegalArgumentException {@literal value == null}
* @throws IllegalArgumentException {@literal formatPattern == null || formatPatter.length() == 0}.
*/
public NumberCell(final T value, final String formatPattern) {
this(value, formatPattern, false);
}
/**
* 値と、書式のインデックス番号、書式を指定するコンストラクタ。
* @param value フォーマット対象の値。
* @param formatIndex フォーマットのインデックス番号。
* @param formatPattern Excelの書式。
* @throws IllegalArgumentException {@literal value == null}
* @throws IllegalArgumentException {@literal formatIndex < 0}
* @throws IllegalArgumentException {@literal formatPattern == null || formatPatter.length() == 0}.
*
*/
public NumberCell(final T value, final short formatIndex, final String formatPattern) {
this(value, formatIndex, formatPattern, false);
}
/**
* 値と書式のインデックス番号を指定するコンストラクタ。
* <p>フォーマットの書式は、{@literal null}になります。
* @param value フォーマット対象の値。
* @param formatIndex 書式のインデックス番号。
* @param dateStart1904 1904年始まりかどうか。
* @throws IllegalArgumentException {@literal value == null}.
* @throws IllegalArgumentException {@literal formatIndex < 0}
*
*/
public NumberCell(final T value, final short formatIndex, final boolean dateStart1904) {
super(value, formatIndex);
this.number = toDouble(value);
this.dateStart1904 = dateStart1904;
}
/**
* 値とその書式を指定するコンストラクタ。
* <p>フォーマットのインデックス番号は、{@literal 0}となります。
* @param value フォーマット対象の値。
* @param formatPattern Excelの書式。
* @param dateStart1904 1904年始まりかどうか。
* @param dateStart1904 1904年始まりかどうか。
* @throws IllegalArgumentException {@literal value == null}
* @throws IllegalArgumentException {@literal formatPattern == null || formatPatter.length() == 0}.
*/
public NumberCell(final T value, final String formatPattern, final boolean dateStart1904) {
super(value, formatPattern);
this.number = toDouble(value);
this.dateStart1904 = dateStart1904;
}
/**
* 値と、書式のインデックス番号、書式を指定するコンストラクタ。
* @param value フォーマット対象の値。
* @param formatIndex フォーマットのインデックス番号。
* @param formatPattern Excelの書式。
* @throws IllegalArgumentException {@literal value == null}
* @throws IllegalArgumentException {@literal formatIndex < 0}
* @throws IllegalArgumentException {@literal formatPattern == null || formatPatter.length() == 0}.
*
*/
public NumberCell(final T value, final short formatIndex, final String formatPattern, final boolean dateStart1904) {
super(value, formatIndex, formatPattern);
this.number = toDouble(value);
this.dateStart1904 = dateStart1904;
}
private double toDouble(final Object value) {
final Class<?> clazz = value.getClass();
if(clazz.isPrimitive()) {
if(clazz.equals(Byte.TYPE)) {
return new BigDecimal((byte) value).doubleValue();
} else if(clazz.equals(Short.TYPE)) {
return new BigDecimal((short) value).doubleValue();
} else if(clazz.equals(Integer.TYPE)) {
return new BigDecimal((int) value).doubleValue();
} else if(clazz.equals(Long.TYPE)) {
return new BigDecimal((long) value).doubleValue();
} else if(clazz.equals(Float.TYPE)) {
return new BigDecimal((float) value).doubleValue();
} else if(clazz.equals(Double.TYPE)) {
return new BigDecimal((double) value).doubleValue();
}
}
if(value instanceof Byte) {
return new BigDecimal((byte) value).doubleValue();
} else if(value instanceof Short) {
return new BigDecimal((short) value).doubleValue();
} else if(value instanceof Integer) {
return new BigDecimal((int) value).doubleValue();
} else if(value instanceof Long) {
return new BigDecimal((long) value).doubleValue();
} else if(value instanceof Float) {
return new BigDecimal((float) value).doubleValue();
} else if(value instanceof Double) {
return new BigDecimal((double) value).doubleValue();
}
if(value instanceof AtomicInteger) {
return new BigDecimal(((AtomicInteger) value).get()).doubleValue();
} else if(value instanceof AtomicLong) {
return new BigDecimal(((AtomicLong) value).get()).doubleValue();
}
if(value instanceof BigDecimal) {
return ((BigDecimal) value).doubleValue();
} else if(value instanceof BigInteger) {
return ((BigInteger) value).doubleValue();
}
throw new IllegalArgumentException("not support type class : " + clazz.getName());
}
/**
* {@inheritDoc}
* <p>常に{@literal true}を返します。
*/
@Override
public boolean isNumber() {
return true;
}
@Override
public double getNumberCellValue() {
return number;
}
@Override
public Date getDateCellValue() {
return ExcelDateUtils.convertJavaDate(number, isDateStart1904());
}
@Override
public boolean isDateStart1904() {
return dateStart1904;
}
}