前言

最近项目上做个需求,需要将成绩导出成excel多个sheet中,针对平均分、百分比这类的值数据库存的是浮点数,所以在展示的时候我们一般保留小数后2位小数。

我们常见的处理办法:

  1. 通过计算之后直接在数据库中保存保留2位小数的值;
  2. 通过写SQL的时候查询的时候直接处理,比如使用ROUND(X,D) 函数、FORMAT(X,D)等函数;
  3. 通过代码实现进行保留小数处理;
  4. 项目使用的EasyExcel通过打注解的方式,导出自动保留2位小数。

综上,为了保证最高的兼容性和耦合性,直接采用注解导出的时候格式化。

EasyExcel介绍

EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。

官方网站:https://easyexcel.opensource.alibaba.com/

github地址:https://github.com/alibaba/easyexcel

gitee地址:https://gitee.com/easyexcel/easyexcel

使用

  1. 导出模型demo:

       //省略......
        @ExcelProperty(value = "语文", order = 1)
        @ContentStyle(dataFormat = 2)
        private Double yw;
        @ExcelProperty(value = "数学", order = 2)
        @ContentStyle(dataFormat = 2)
        private Double sx;
  2. @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典藏版)

文章目录