eec
eec copied to clipboard
相同的两列小数,一列取到的值正常,一列取到科学计数法
我看了单元格的格式都是数字
方便的话可以将样本发我一份,[email protected]
样本已发至邮箱
发自我的iPhone
在 2021年4月28日,12:12,wangguanquan @.***> 写道:
@.***
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.
应该是浮点数精度引起的,文件内部保存的原始值就是0.08
和7.0000000000000007E-2
<c r="L19" s="30"><v>0.08</v></c><c r="M19" s="30"><v>7.0000000000000007E-2</v></c>
不过eec可以像jdbc的一样读取内容,调用row.getDouble(12)
或者row.getDecimal(12)
获取值,样本文件读出的double数据为0.07
,decimal数据为0.070000000000000007
,所以你现在知道为什么第二个数是用科学计数法了,因为精度太大了。
测试代码如下:
try (ExcelReader reader = ExcelReader.read(Paths.get("./八一系统模板发票TEYASI1.xlsx"))) {
reader.sheet(0).rows().filter(row -> row.getRowNumber() > 17 && !row.isEmpty()).forEach(row -> println(row.getDouble(12)));
reader.sheet(0).reset(); // 重置位置,这样就可以重复读了
println("-------------DECIMAL-------------");
reader.sheet(0).rows().filter(row -> row.getRowNumber() > 17 && !row.isEmpty()).forEach(row -> println(row.getDecimal(12)));
} catch (IOException e) {
e.printStackTrace();
}
更好的,你可以将列表转为对象,这样就可以指定类型了,你可以定义如下实体,
public class Item {
@ExcelColumn("亚马逊FBA子单号/箱唛号")
private String fbaNo;
@ExcelColumn("Reference ID(亚马逊追踪编码)")
private String refId;
@ExcelColumn("单个产品申报单价")
private BigDecimal price;
@ExcelColumn("单个产品净重KG(必填)")
private BigDecimal weight;
@Override
public String toString() {
return "fbaNo: " + fbaNo + ", refId: " + refId + ", price: " + price + ", weight: " + weight;
}
}
// 测试代码
reader.sheet(0).reset();
reader.sheet(0).rows()
.filter(row -> row.getRowNumber() > 16 && !row.isEmpty()) // 这里从第16行开始,因为这一行包含头部信息
.map(row -> row.too(Item.class)) // 转为Item对象
.filter(Objects::nonNull)
.forEach(Print::println);
会读取如下数据
fbaNo: FBA15DRV4JP4U000001, refId: 2Z91JHMR, price: 0.08, weight: 0.070000000000000007
fbaNo: FBA15DRV4JP4U000002, refId: 2Z91JHMR, price: 0.08, weight: 0.070000000000000007
fbaNo: FBA15DRV4JP4U000003, refId: 2Z91JHMR, price: 0.08, weight: 0.070000000000000007
fbaNo: FBA15DRV4JP4U000004, refId: 2Z91JHMR, price: 0.08, weight: 0.070000000000000007
fbaNo: FBA15DRV4JP4U000005, refId: 2Z91JHMR, price: 0.08, weight: 0.070000000000000007
fbaNo: FBA15DRV4JP4U000006, refId: 2Z91JHMR, price: 0.08, weight: 0.070000000000000007
fbaNo: FBA15DRV4JP4U000007, refId: 2Z91JHMR, price: 0.08, weight: 0.070000000000000007
fbaNo: FBA15DRV4JP4U000008, refId: 2Z91JHMR, price: 0.08, weight: 0.070000000000000007
fbaNo: FBA15DRV4JP4U000009, refId: 2Z91JHMR, price: 0.08, weight: 0.070000000000000007
fbaNo: FBA15DRV4JP4U000010, refId: 2Z91JHMR, price: 0.08, weight: 0.070000000000000007
fbaNo: FBA15DRV4JP4U000011, refId: 2Z91JHMR, price: 0.08, weight: 0.070000000000000007
fbaNo: FBA15DRV7YTGU000001, refId: 87EL4DRZ, price: 0.08, weight: 0.070000000000000007
是否可通过 CellType.DOUBLE.equals(row.getCellType(i)) 来判断 Cell类型 从而确定是否可以使用row.getDecimal(12) 或 row.getDouble(12)来获取数据?
不可以的,Office是Number类的,并不区分Double和Decimal,只是在java端区分并转换,其实你完全可以根据业务来决定使用哪种类型,或者决定保留几位精度,或者直接使用string类型。
我现在就是用row.getString(i),获取出来有时候就会是科学计数法。业务上因为模板的每列数据类型不是固定的 ,可能有的模板数字在第10列,有的模板在第11列,所以不太好判断哪列可以使用获取getDouble()或者getDecimal(),所以我的想法就是能不能确定了格子的数据格式 然后直接使用对应的方法。
#getCellType
返回单元格的类型,理论上只有numeric,string, boolean这三种,如果是numeric内部还会进一步根据单元格设置了格式化判断是否可能是date
刚测试了一下,CellType 这个枚举类里面的类型都有