引入依赖

 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>1.1.2-beat1</version></dependency>

读取excel文件

小于1000行数据

默认读取

读取Sheet1的全部数据

String filePath = "D:\\导入模板11条.xlsx";
List<Object> objects = ExcelUtil.readLessThan1000Row(filePath);

指定读取

获取Sheet1表头以下的信息

String filePath = "D:\\导入模板11条.xlsx";
//第一个1代表sheet1, 第二个1代表从第几行开始读取数据,行号最小值为0
Sheet sheet = new Sheet(1, 1);
List<Object> objects = ExcelUtil.readLessThan1000Row(filePath,sheet);

获取Sheet2的所有信息

 String filePath = "D:\\导入模板11条.xlsx";Sheet sheet = new Sheet(2, 0);List<Object> objects = ExcelUtil.readLessThan1000Row(filePath,sheet);

大于1000行数据

默认读取

String filePath = "D:\\导入模板11条.xlsx";
List<Object> objects = ExcelUtil.readMoreThan1000Row(filePath);

指定读取

String filePath = "D:\\导入模板11条.xlsx";
Sheet sheet = new Sheet(1, 2);
List<Object> objects = ExcelUtil.readMoreThan1000Row(filePath,sheet);

导出excle

单个Sheet导出

无模型映射导出

String filePath = "/home/Downloads/测试.xlsx";
List<List<Object>> data = new ArrayList<>();
data.add(Arrays.asList("111","222","333"));
data.add(Arrays.asList("111","222","333"));
data.add(Arrays.asList("111","222","333"));
List<String> head = Arrays.asList("表头1", "表头2", "表头3");
ExcelUtil.writeBySimple(filePath,data,head);

模型映射导出

1、定义好模型对象

package com.springboot.utils.excel.test;import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;
import lombok.Data;
import lombok.EqualsAndHashCode;@EqualsAndHashCode(callSuper = true)
@Data
public class TableHeaderExcelProperty extends BaseRowModel {/*** value: 表头名称* index: 列的号, 0表示第一列*/@ExcelProperty(value = "姓名", index = 0)private String name;@ExcelProperty(value = "年龄",index = 1)private int age;@ExcelProperty(value = "学校",index = 2)private String school;
}

2、调用方法

String filePath = "/home/Downloads/测试.xlsx";
ArrayList<TableHeaderExcelProperty> data = new ArrayList<>();for(int i = 0; i < 4; i++){TableHeaderExcelProperty tableHeaderExcelProperty = new TableHeaderExcelProperty();tableHeaderExcelProperty.setName("cmj" + i);tableHeaderExcelProperty.setAge(22 + i);tableHeaderExcelProperty.setSchool("清华大学" + i);data.add(tableHeaderExcelProperty);}ExcelUtil.writeWithTemplate(filePath,data);

多个Sheet导出

1、定义好模型对象

package com.springboot.utils.excel.test;import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;
import lombok.Data;
import lombok.EqualsAndHashCode;@EqualsAndHashCode(callSuper = true)
@Data
public class TableHeaderExcelProperty extends BaseRowModel {/*** value: 表头名称* index: 列的号, 0表示第一列*/@ExcelProperty(value = "姓名", index = 0)private String name;@ExcelProperty(value = "年龄",index = 1)private int age;@ExcelProperty(value = "学校",index = 2)private String school;
}

2、调用方法

 ArrayList<ExcelUtil.MultipleSheelPropety> list1 = new ArrayList<>();for(int j = 1; j < 4; j++){ArrayList<TableHeaderExcelProperty> list = new ArrayList<>();for(int i = 0; i < 4; i++){TableHeaderExcelProperty tableHeaderExcelProperty = new TableHeaderExcelProperty();tableHeaderExcelProperty.setName("cmj" + i);tableHeaderExcelProperty.setAge(22 + i);tableHeaderExcelProperty.setSchool("清华大学" + i);list.add(tableHeaderExcelProperty);}Sheet sheet = new Sheet(j, 0);sheet.setSheetName("sheet" + j);ExcelUtil.MultipleSheelPropety multipleSheelPropety = new ExcelUtil.MultipleSheelPropety();multipleSheelPropety.setData(list);multipleSheelPropety.setSheet(sheet);list1.add(multipleSheelPropety);}ExcelUtil.writeWithMultipleSheel("/home/chenmingjian/Downloads/aaa.xlsx",list1);

工具类

1、excel工具类

package com.springboot.utils.excel;import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;@Slf4j
public class ExcelUtil {private static Sheet initSheet;static {initSheet = new Sheet(1, 0);initSheet.setSheetName("sheet");//设置自适应宽度initSheet.setAutoWidth(Boolean.TRUE);}/*** 读取少于1000行数据* @param filePath 文件绝对路径* @return*/public static List<Object> readLessThan1000Row(String filePath){return readLessThan1000RowBySheet(filePath,null);}/*** 读小于1000行数据, 带样式* filePath 文件绝对路径* initSheet :*      sheetNo: sheet页码,默认为1*      headLineMun: 从第几行开始读取数据,默认为0, 表示从第一行开始读取*      clazz: 返回数据List<Object> 中Object的类名*/public static List<Object> readLessThan1000RowBySheet(String filePath, Sheet sheet){if(!StringUtils.hasText(filePath)){return null;}sheet = sheet != null ? sheet : initSheet;InputStream fileStream = null;try {fileStream = new FileInputStream(filePath);return EasyExcelFactory.read(fileStream, sheet);} catch (FileNotFoundException e) {log.info("找不到文件或文件路径错误, 文件:{}", filePath);}finally {try {if(fileStream != null){fileStream.close();}} catch (IOException e) {log.info("excel文件读取失败, 失败原因:{}", e);}}return null;}/*** 读大于1000行数据* @param filePath 文件觉得路径* @return*/public static List<Object> readMoreThan1000Row(String filePath){return readMoreThan1000RowBySheet(filePath,null);}/*** 读大于1000行数据, 带样式* @param filePath 文件觉得路径* @return*/public static List<Object> readMoreThan1000RowBySheet(String filePath, Sheet sheet){if(!StringUtils.hasText(filePath)){return null;}sheet = sheet != null ? sheet : initSheet;InputStream fileStream = null;try {fileStream = new FileInputStream(filePath);ExcelListener excelListener = new ExcelListener();EasyExcelFactory.readBySax(fileStream, sheet, excelListener);return excelListener.getDatas();} catch (FileNotFoundException e) {log.error("找不到文件或文件路径错误, 文件:{}", filePath);}finally {try {if(fileStream != null){fileStream.close();}} catch (IOException e) {log.error("excel文件读取失败, 失败原因:{}", e);}}return null;}/*** 生成excle* @param filePath  绝对路径, 如:/home/chenmingjian/Downloads/aaa.xlsx* @param data 数据源* @param head 表头*/public static void writeBySimple(String filePath, List<List<Object>> data, List<String> head){writeSimpleBySheet(filePath,data,head,null);}/*** 生成excle* @param filePath 绝对路径, 如:/home/chenmingjian/Downloads/aaa.xlsx* @param data 数据源* @param sheet excle页面样式* @param head 表头*/public static void writeSimpleBySheet(String filePath, List<List<Object>> data, List<String> head, Sheet sheet){sheet = (sheet != null) ? sheet : initSheet;if(head != null){List<List<String>> list = new ArrayList<>();head.forEach(h -> list.add(Collections.singletonList(h)));sheet.setHead(list);}OutputStream outputStream = null;ExcelWriter writer = null;try {outputStream = new FileOutputStream(filePath);writer = EasyExcelFactory.getWriter(outputStream);writer.write1(data,sheet);} catch (FileNotFoundException e) {log.error("找不到文件或文件路径错误, 文件:{}", filePath);}finally {try {if(writer != null){writer.finish();}if(outputStream != null){outputStream.close();}} catch (IOException e) {log.error("excel文件导出失败, 失败原因:{}", e);}}}/*** 生成excle* @param filePath 绝对路径, 如:/home/chenmingjian/Downloads/aaa.xlsx* @param data 数据源*/public static void writeWithTemplate(String filePath, List<? extends BaseRowModel> data){writeWithTemplateAndSheet(filePath,data,null);}/*** 生成excle* @param filePath 绝对路径, 如:/home/chenmingjian/Downloads/aaa.xlsx* @param data 数据源* @param sheet excle页面样式*/public static void writeWithTemplateAndSheet(String filePath, List<? extends BaseRowModel> data, Sheet sheet){if(CollectionUtils.isEmpty(data)){return;}sheet = (sheet != null) ? sheet : initSheet;sheet.setClazz(data.get(0).getClass());OutputStream outputStream = null;ExcelWriter writer = null;try {outputStream = new FileOutputStream(filePath);writer = EasyExcelFactory.getWriter(outputStream);writer.write(data,sheet);} catch (FileNotFoundException e) {log.error("找不到文件或文件路径错误, 文件:{}", filePath);}finally {try {if(writer != null){writer.finish();}if(outputStream != null){outputStream.close();}} catch (IOException e) {log.error("excel文件导出失败, 失败原因:{}", e);}}}/*** 生成多Sheet的excle* @param filePath 绝对路径, 如:/home/chenmingjian/Downloads/aaa.xlsx* @param multipleSheelPropetys*/public static void writeWithMultipleSheel(String filePath,List<MultipleSheelPropety> multipleSheelPropetys){if(CollectionUtils.isEmpty(multipleSheelPropetys)){return;}OutputStream outputStream = null;ExcelWriter writer = null;try {outputStream = new FileOutputStream(filePath);writer = EasyExcelFactory.getWriter(outputStream);for (MultipleSheelPropety multipleSheelPropety : multipleSheelPropetys) {Sheet sheet = multipleSheelPropety.getSheet() != null ? multipleSheelPropety.getSheet() : initSheet;if(!CollectionUtils.isEmpty(multipleSheelPropety.getData())){sheet.setClazz(multipleSheelPropety.getData().get(0).getClass());}writer.write(multipleSheelPropety.getData(), sheet);}} catch (FileNotFoundException e) {log.error("找不到文件或文件路径错误, 文件:{}", filePath);}finally {try {if(writer != null){writer.finish();}if(outputStream != null){outputStream.close();}} catch (IOException e) {log.error("excel文件导出失败, 失败原因:{}", e);}}}/*********************匿名内部类开始,可以提取出去******************************/@Datapublic static class MultipleSheelPropety{private List<? extends BaseRowModel> data;private Sheet sheet;}/*** 解析监听器,* 每解析一行会回调invoke()方法。* 整个excel解析结束会执行doAfterAllAnalysed()方法** @author: chenmingjian* @date: 19-4-3 14:11*/@Getter@Setterpublic static class ExcelListener extends AnalysisEventListener {private List<Object> datas = new ArrayList<>();/*** 逐行解析* object : 当前行的数据*/@Overridepublic void invoke(Object object, AnalysisContext context) {//当前行// context.getCurrentRowNum()if (object != null) {datas.add(object);}}/*** 解析完所有数据后会调用该方法*/@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {//解析结束销毁不用的资源}}/************************匿名内部类结束,可以提取出去***************************/}

2、日期格式类

package com.springboot.util;
import org.springframework.util.StringUtils;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;public class DateUtil {public static final String YYYYMMDDHHMMSS = "yyyy-MM-dd HH:mm:ss";public static final String YYYYMMDD = "yyyy-MM-dd";public static final String YYYYMMDDHHMM = "yyyy-MM-dd HH:mm";public static final String YYYYMM = "yyyy-MM";public DateUtil() {}public static String getCurrentDate(String var1) {return (new SimpleDateFormat(var1)).format(new Date());}public static Date parse(String date) {if (StringUtils.isEmpty(date)) {return null;} else {try {return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parse(date);} catch (ParseException var2) {return null;}}}public static Date parse(String date, String format) {if (StringUtils.isEmpty(date)) {return null;} else {try {return (new SimpleDateFormat(format)).parse(date);} catch (ParseException var3) {return null;}}}public static Date parseToYMD(String date) {try {return (new SimpleDateFormat("yyyy-MM-dd")).parse(date);} catch (ParseException var2) {return null;}}public static String format(Date date) {return date != null ? (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(date) : "/";}public static String format(Date date, String format) {return (new SimpleDateFormat(format)).format(date);}public static Date addYear(Date date, int year) {Calendar calendar = new GregorianCalendar();calendar.setTime(date);calendar.add(1, year);date = calendar.getTime();return date;}public static Date addMonth(Date date, int month) {Calendar calendar = new GregorianCalendar();calendar.setTime(date);calendar.add(2, month);date = calendar.getTime();return date;}public static Date addDay(Date date, int day) {Calendar calendar = new GregorianCalendar();calendar.setTime(date);calendar.add(5, day);date = calendar.getTime();return date;}public static Date addHour(Date date, int day) {Calendar calendar = new GregorianCalendar();calendar.setTime(date);calendar.add(10, day);date = calendar.getTime();return date;}public static Date addMinute(Date date, int day) {Calendar calendar = new GregorianCalendar();calendar.setTime(date);calendar.add(12, day);date = calendar.getTime();return date;}public static Date addWeek(Date date, int day) {Calendar calendar = new GregorianCalendar();calendar.setTime(date);calendar.add(5, day);date = calendar.getTime();return date;}public static Long getTimestamp() {return System.currentTimeMillis();}public static Map<String, String> getCurrentWeek(boolean addEndDay) {Map<String, String> map = new HashMap(2);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Calendar cal = Calendar.getInstance();cal.setFirstDayOfWeek(2);int dayWeek = cal.get(7);if (dayWeek == 1) {dayWeek = 8;}cal.add(5, cal.getFirstDayOfWeek() - dayWeek);Date mondayDate = cal.getTime();String weekBegin = sdf.format(mondayDate);map.put("beginWeek", weekBegin);cal.add(5, 4 + cal.getFirstDayOfWeek());if (addEndDay) {cal.add(5, 1);}Date sundayDate = cal.getTime();String weekEnd = sdf.format(addDay(sundayDate, -1)) + " 23:59:59";map.put("endWeek", weekEnd);return map;}public static Map<String, String> getCurrentMonth(boolean addEndDay) {Map<String, String> map = new HashMap(2);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");map.put("beginMonth", format(new Date(), "yyyy-MM") + "-01");Calendar calendar = Calendar.getInstance();calendar.setTime(new Date());calendar.set(5, calendar.getActualMaximum(5));if (addEndDay) {calendar.add(5, 1);}map.put("endMonth", sdf.format(calendar.getTime()));return map;}public static Map<String, String> getAppointMonth(Date date, boolean addEndDay) {Map<String, String> map = new HashMap(2);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");map.put("beginMonth", format(date, "yyyy-MM") + "-01");Calendar calendar = Calendar.getInstance();calendar.setTime(date);calendar.set(5, calendar.getActualMaximum(5));if (addEndDay) {calendar.add(5, 1);}map.put("endMonth", sdf.format(calendar.getTime()));return map;}public static String secondToTime(long second) {long days = second / 86400L;second %= 86400L;long hours = second / 3600L;second %= 3600L;long minutes = second / 60L;second %= 60L;return 0L < days ? days + "天" + hours + "小时" + minutes + "分" + second + "秒" : hours + "小时" + minutes + "分" + second + "秒";}public static int getYear(Date date) {SimpleDateFormat sdf = new SimpleDateFormat("YYYY");return Integer.valueOf(sdf.format(date));}public static Date getYearFirst(int year) {Calendar calendar = Calendar.getInstance();calendar.clear();calendar.set(1, year);Date currYearFirst = calendar.getTime();return currYearFirst;}public static Date getYearLast(int year) {Calendar calendar = Calendar.getInstance();calendar.clear();calendar.set(1, year);calendar.roll(6, -1);Date currYearLast = calendar.getTime();return currYearLast;}
}

测试类

 public void testEasyExcel(@RequestParam Integer type){String filePath = "D:\\导入模板11条.xlsx";List<Object> objects = ExcelUtil.readLessThan1000Row(filePath);for (Object object : objects){String[] split = object.toString().split(",");logger.info("数据列:{},数据列:{},最后一个数据:{}",split[0],split.length,split[split.length-1]);int date = 0;try {String param = split[6];String stringNotBlank = getStringNotBlank(param);date = Integer.parseInt(stringNotBlank);}catch (Exception e){e.printStackTrace();}String date1 = formatExcelDate(date);Date obj = null;try {if (date1.matches("\\d{4}/\\d{1,2}/\\d{1,2}")) {obj= DateUtil.parse(date1, "yyyy/MM/dd");} else if (date1.matches("\\d{4}-\\d{2}-\\d{2}")) {obj=DateUtil.parse(date1, "yyyy-MM-dd");} else if (date1.matches("^\\d{4}\\d{2}\\d{2}")) {obj=DateUtil.parse(date1, "yyyyMMdd");} else if (date1.matches("\\d{4}.\\d{1,2}.\\d{1,2}")) {obj=DateUtil.parse(date1, "yyyy.MM.dd");} else {obj=null;}}catch (Exception e){e.printStackTrace();}logger.info("日期:{}",obj);}}/*** 格式化Excel时间* @param day* @return yyyy-MM-dd*/private String formatExcelDate(int day) {Calendar calendar = new GregorianCalendar(1900,0,-1);Date gregorianDate = calendar.getTime();String formatExcelDate = DateUtil.format(DateUtil.addDay(gregorianDate, day), DateUtil.YYYYMMDD);return formatExcelDate;}/*** string类型去掉前后空字符* @return*/public String getStringNotBlank(String textContent){textContent = textContent.trim();//这里判断是不是全角空格while (textContent.startsWith(" ")) {textContent = textContent.substring(1, textContent.length()).trim();}while (textContent.endsWith(" ")) {textContent = textContent.substring(0, textContent.length() - 1).trim();}return textContent;}

问题:

1、使用 EasyExcel 读取 Excel 数据时,表格中的日期自动转化为了一串数字

原因:

因为 Excel 导入的时间是以1900 年为原点的,而数字 34839 和 36577 则是1995/5/20 和 2000/2/21 与 1900 年之间经过的天数差值。

解决办法:

/*** 格式化Excel时间* @param day* @return yyyy-MM-dd*/private String formatExcelDate(int day) {Calendar calendar = new GregorianCalendar(1900,0,-1);Date gregorianDate = calendar.getTime();String formatExcelDate = DateUtils.format(DateUtils.addDay(gregorianDate, day), DateUtils.YYYYMMDD);return formatExcelDate;}

2、表格中的日期自动转化为一串数字时前后会带空字符 导致string转number报错

解决办法:

/*** string类型去掉前后空字符* @return*/public String getStringNotBlank(String textContent){textContent = textContent.trim();//这里判断是不是全角空格while (textContent.startsWith(" ")) {textContent = textContent.substring(1, textContent.length()).trim();}while (textContent.endsWith(" ")) {textContent = textContent.substring(0, textContent.length() - 1).trim();}return textContent;}

easyexcel使用和遇到的问题点相关推荐

  1. easyexcel生成excel_阿里JAVA解析Excel工具easyexcel

    java解析.生成Excel比较有名的框架有Apache poi.jxl.但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有 ...

  2. easyexcel怎么设置表头宽度_easyexcel 自动设置列宽

    com.alibaba easyexcel 2.1.4 导出controller层代码 @RequestMapping("/download") public void downl ...

  3. Spring Boot + EasyExcel 导入导出,好用到爆,可以扔掉 POI 了!

    欢迎关注方志朋的博客,回复"666"获面试宝典 一.EasyExcel EasyExcel是阿里巴巴开源poi插件之一,主要解决了poi框架使用复杂,sax解析模式不容易操作,数据 ...

  4. 史上最全的Excel导入导出(easyexcel版)

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:blog.csdn.net/qq_32258777/article/details/89031479 喝水不忘挖井人,感谢阿里 ...

  5. easyexcel导入时读不到数据_EasyExcel简单使用--导入excel数据

    读Excel 1.依赖包 com.alibaba easyexcel 2.0.5 2.代码import java.io.File; import com.alibaba.excel.EasyExcel ...

  6. easyexcel工具类_阿里巴巴程序员常用的 15 款开发者工具

    从人工到自动化,从重复到创新,技术演进的历程中,伴随着开发者工具类产品的发展. 阿里巴巴将自身在各类业务场景下的技术积淀,通过开源.云上实现或工具等形式对外开放,本文将精选了一些阿里巴巴的开发者工具, ...

  7. Apache POI和EasyExcel 第七集:EasyExcel的基本操作,读取和写入Excel,一行足矣

    Apache POI和EasyExcel 第七集:EasyExcel的基本操作,读取和写入Excel,一行搞定 一.资源 在这里设置lombok会遇到一个问题,以前在springboot那里都没遇到, ...

  8. Apache POI和EasyExcel 第六集:Apache POI的Excel读取单元格中的计算公式

    Apache POI和EasyExcel 第六集:Apache POI的Excel读取单元格中的计算公式 一.资源 代码实现中的带有计算公式的Excel(xls) 链接:https://pan.bai ...

  9. Apache POI和EasyExcel 第五集:Apache POI的Excel读取不同类型的数据

    Apache POI和EasyExcel 第五集:Apache POI的Excel读取不同类型的数据 一.资源 什么是Apache POI Apache POI 不同类型的数据的表格(xls) 链接: ...

  10. Apache POI和EasyExcel 第四集:Apache POI的Excel基本读取(分为03版的xls、07版的xlsx)

    Apache POI和EasyExcel 第四集:Apache POI的Excel基本读取(分为03版的xls.07版的xlsx) 一.资源 一个十分好用的日期类型处理包,和Java8搭配使用非常好 ...

最新文章

  1. ubuntu系统安装FTP
  2. 入围CVPR最佳论文,这项AI基础研究让我们对虎牙刮目相看
  3. 网站导航目录要该如何优化?
  4. 聚焦和增强卷积神经网络
  5. 【封装那些事】 缺失封装
  6. 本地生活服务 巨头们玩不转的电商蓝海
  7. mysql中tinyint、smallint、int、bigint的区别介绍
  8. 深入理解ElasticSearch(八):索引管理
  9. Cassandra1.2文档学习(7)—— 规划集群部署
  10. 将远程计算机上的文件夹,如何将现有网站上虚拟目录创建到驻留在远程计算机上的文件夹...
  11. LAMP默认安装路径
  12. 24.卷1(套接字联网API)---带外数据
  13. Error: Invalid or corrupt
  14. django使用mysql函数_请问django 可以操作mysql函数么?
  15. 列表左右移动 2017-03-23
  16. cat /proc/cpuinfo命令详解
  17. 西瓜视频4K修复技术还原经典,为内容创新打开新思路
  18. python正则匹配中文
  19. NYOJ_1275 导弹发射 【LIS】
  20. 【读书笔记】【程序员的自我修养 -- 链接、装载与库(三)】函数调用与栈(this指针、返回值传递临时对象构建栈、运行库与多线程、_main函数、系统调用与中断向量表、Win32、可变参数、大小端

热门文章

  1. W3Cshool中的mysql命令说明及用法。转载自W3school
  2. 2022年湖北特种作业操作证应急管理厅怎么报考?甘建二
  3. 给IT人士的保健建议
  4. 高效率开发Web安全扫描器之路(一)
  5. 谷歌浏览器默认开启无痕浏览
  6. STM32学习记录——声音传感器的使用
  7. 无聊的一天,就用python随便做个控制台小游戏吧
  8. ORACLE简繁转换函数
  9. 深度学习完全攻略!(连载十二:SSD网络理解)
  10. 常用统计数学公式学习(1)方差与期望值