前言
最近项目上做个需求,需要将成绩导出成excel多个sheet中,针对平均分、百分比这类的值数据库存的是浮点数,所以在展示的时候我们一般保留小数后2位小数。
我们常见的处理办法:
- 通过计算之后直接在数据库中保存保留2位小数的值;
- 通过写SQL的时候查询的时候直接处理,比如使用
ROUND(X,D)
函数、FORMAT(X,D)
等函数; - 通过代码实现进行保留小数处理;
- 项目使用的EasyExcel通过打注解的方式,导出自动保留2位小数。
综上,为了保证最高的兼容性和耦合性,直接采用注解导出的时候格式化。
EasyExcel介绍
EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。
官方网站:https://easyexcel.opensource.alibaba.com/
github地址:https://github.com/alibaba/easyexcel
gitee地址:https://gitee.com/easyexcel/easyexcel
使用
导出模型demo:
代码语言:javascript复制 //省略......
@ExcelProperty(value = "语文", order = 1)
@ContentStyle(dataFormat = 2)
private Double yw;
@ExcelProperty(value = "数学", order = 2)
@ContentStyle(dataFormat = 2)
private Double sx;
@ContentStyle注解对应的dataFormat
=2 ,这个注解的dataFormat就是设置格式的,他的值是BuiltinFormats
类中_formats数组中对应格式的下标,源码如下:
package org.apache.poi.ss.usermodel;
/**
* Utility to identify built-in formats. The following is a list of the formats as
* returned by this class.<p>
*<p>
* 0, "General"<br>
* 1, "0"<br>
* 2, "0.00"<br>
* 3, "#,##0"<br>
* 4, "#,##0.00"<br>
* 5, "$#,##0_);($#,##0)"<br>
* 6, "$#,##0_);[Red]($#,##0)"<br>
* 7, "$#,##0.00);($#,##0.00)"<br>
* 8, "$#,##0.00_);[Red]($#,##0.00)"<br>
* 9, "0%"<br>
* 0xa, "0.00%"<br>
* 0xb, "0.00E 00"<br>
* 0xc, "# ?/?"<br>
* 0xd, "# ??/??"<br>
* 0xe, "m/d/yy"<br>
* 0xf, "d-mmm-yy"<br>
* 0x10, "d-mmm"<br>
* 0x11, "mmm-yy"<br>
* 0x12, "h:mm AM/PM"<br>
* 0x13, "h:mm:ss AM/PM"<br>
* 0x14, "h:mm"<br>
* 0x15, "h:mm:ss"<br>
* 0x16, "m/d/yy h:mm"<br>
*<p>
* // 0x17 - 0x24 reserved for international and undocumented
* 0x25, "#,##0_);(#,##0)"<br>
* 0x26, "#,##0_);[Red](#,##0)"<br>
* 0x27, "#,##0.00_);(#,##0.00)"<br>
* 0x28, "#,##0.00_);[Red](#,##0.00)"<br>
* 0x29, "_(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)"<br>
* 0x2a, "_($* #,##0_);_($* (#,##0);_($* "-"_);_(@_)"<br>
* 0x2b, "_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)"<br>
* 0x2c, "_($* #,##0.00_);_($* (#,##0.00);_($* "-"??_);_(@_)"<br>
* 0x2d, "mm:ss"<br>
* 0x2e, "[h]:mm:ss"<br>
* 0x2f, "mm:ss.0"<br>
* 0x30, "##0.0E 0"<br>
* 0x31, "@" - This is text format.<br>
* 0x31 "text" - Alias for "@"<br>
* <p>
*/
public final class BuiltinFormats {
/**
* The first user-defined number format starts at 164.
*/
public static final int FIRST_USER_DEFINED_FORMAT_INDEX = 164;
private final static String[] _formats = {
"General",
"0",
"0.00",
"#,##0",
"#,##0.00",
""$"#,##0_);("$"#,##0)",
""$"#,##0_);[Red]("$"#,##0)",
""$"#,##0.00_);("$"#,##0.00)",
""$"#,##0.00_);[Red]("$"#,##0.00)",
"0%",
"0.00%",
"0.00E 00",
"# ?/?",
"# ??/??",
"m/d/yy",
"d-mmm-yy",
"d-mmm",
"mmm-yy",
"h:mm AM/PM",
"h:mm:ss AM/PM",
"h:mm",
"h:mm:ss",
"m/d/yy h:mm",
// 0x17 - 0x24 reserved for international and undocumented
// TODO - one junit relies on these values which seems incorrect
"reserved-0x17",
"reserved-0x18",
"reserved-0x19",
"reserved-0x1A",
"reserved-0x1B",
"reserved-0x1C",
"reserved-0x1D",
"reserved-0x1E",
"reserved-0x1F",
"reserved-0x20",
"reserved-0x21",
"reserved-0x22",
"reserved-0x23",
"reserved-0x24",
"#,##0_);(#,##0)",
"#,##0_);[Red](#,##0)",
"#,##0.00_);(#,##0.00)",
"#,##0.00_);[Red](#,##0.00)",
"_(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)",
"_("$"* #,##0_);_("$"* (#,##0);_("$"* "-"_);_(@_)",
"_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)",
"_("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_)",
"mm:ss",
"[h]:mm:ss",
"mm:ss.0",
"##0.0E 0",
"@"
};
/**
* @return array of built-in data formats
*/
public static String[] getAll() {
return _formats.clone();
}
/**
* Get the format string that matches the given format index
*
* @param index of a built in format
* @return string represented at index of format or <code>null</code> if there is not a built-in format at that index
*/
public static String getBuiltinFormat(int index) {
if (index < 0 || index >=_formats.length) {
return null;
}
return _formats[index];
}
/**
* Get the format index that matches the given format string.<br>
* Automatically converts "text" to excel's format string to represent text.
*
* @param pFmt string matching a built-in format
* @return index of format or -1 if undefined.
*/
public static int getBuiltinFormat(String pFmt) {
String fmt = "TEXT".equalsIgnoreCase(pFmt) ? "@" : pFmt;
int i = -1;
for (String f : _formats) {
i ;
if (f.equals(fmt)) {
return i;
}
}
return -1;
}
}
总结
在项目中,我们往往可以有很多种方式达到需求效果,实际中我们还是多考虑考虑那种方式能够让改动最小,扩展性更强,我们如果采用数据库保留小数,那么可能针对有些地方要使用高精度的值就得不偿失了,所以还是保证原始数据完整性,只用在业务需要的地方进行处理,这样让影响范围降到最低。
技术永远都是为业务需求服务,脱离实际需求谈技术一切都会显得毫无意义。
参考链接
Easy Excel EasyExcel导出保留2位小数 MySql保留两位小数(VIP典藏版)