前言

相信不少同学在开发中都会遇到导出excel这种需求,今天将Excel的导出工具和大家进行一个分享,如有错误还请大佬们批评指正。该工具类可以实现自定义列宽,自定义表头样式,实现了多sheet页合并导出。废话不多,上代码——

一、这是在maven项目中,首先需要引入依赖

<!--引入POI-->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.9</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.9</version>
</dependency>
<!--引入io流-->
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.3</version>
</dependency>

二、 创建Excel导出工具类

package com.xxx.xxx.microsoftOffice;import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.xssf.usermodel.*;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** 导出Excel* @author Ldpy** @param <T>*/
public class ExportExcelUtil<T>{// 2007 版本以上 最大支持1048576行public  final static String  EXCEl_FILE_2007 = "2007";// 2003 版本 最大支持65536 行public  final static String  EXCEL_FILE_2003 = "2003";/*** <p>* 导出无头部标题行Excel <br>* 时间格式默认:yyyy-MM-dd hh:mm:ss <br>* </p>** @param title 表格标题* @param dataset 数据集合* @param response Http响应对象* @param version 2003 或者 2007,不传时默认生成2007版本*/public void exportExcel(XSSFWorkbook workbook, String title, Collection<T> dataset, HttpServletRequest request, HttpServletResponse response, String version, int sheetNum) {if(version != null && EXCEL_FILE_2003.equals(version.trim())){exportExcel2003(title, null, dataset, request, response, "yyyy-MM-dd HH:mm:ss", sheetNum);}else{exportExcel2007(workbook, title, null, dataset, request, response, "yyyy-MM-dd HH:mm:ss", sheetNum);}}/*** <p>* 导出带有头部标题行的Excel <br>* 时间格式默认:yyyy-MM-dd hh:mm:ss <br>* </p>** @param title 表格标题* @param headers 头部标题集合* @param dataset 数据集合* @param response Http响应对象* @param version 2003 或者 2007,不传时默认生成2007版本*/public void exportExcel(XSSFWorkbook workbook, String title,String[] headers, Collection<T> dataset, HttpServletRequest request, HttpServletResponse response,String version, int sheetNum) {if(version != null && EXCEL_FILE_2003.equals(version.trim())){exportExcel2003(title, headers, dataset, request, response, "yyyy-MM-dd HH:mm:ss", sheetNum);}else{exportExcel2007(workbook, title, headers, dataset, request, response, "yyyy-MM-dd HH:mm:ss", sheetNum);}}/*** <p>* 通用Excel导出方法,利用反射机制遍历对象的所有字段,将数据写入Excel文件中 <br>* 此版本生成2007以上版本的文件 (文件后缀:xlsx)* </p>** @param fileName*            表格标题名* @param headers*            表格头部标题集合* @param dataset*            需要显示的数据集合,集合中一定要放置符合JavaBean风格的类的对象。此方法支持的*            JavaBean属性的数据类型有基本数据类型及String,Date* @param response*            与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中* @param pattern*            如果有时间数据,设定输出格式。默认为"yyyy-MM-dd hh:mm:ss"*/@SuppressWarnings({ "unchecked", "rawtypes" })private void exportExcel2007(XSSFWorkbook workbook, String fileName, String[] headers, Collection<T> dataset, HttpServletRequest request, HttpServletResponse response, String pattern, int sheetNum) {// 声明一个工作薄//XSSFWorkbook workbook = new XSSFWorkbook();// 生成一个表格XSSFSheet sheet = workbook.createSheet(fileName);// 设置表格默认列宽度为15个字节sheet.setDefaultColumnWidth(20);// 生成一个样式XSSFCellStyle style = workbook.createCellStyle();// 设置这些样式byte[] rgb = {(byte)132,112,(byte)255};style.setFillForegroundColor(new XSSFColor(rgb));style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);style.setBorderBottom(XSSFCellStyle.BORDER_THIN);style.setBorderLeft(XSSFCellStyle.BORDER_THIN);style.setBorderRight(XSSFCellStyle.BORDER_THIN);style.setBorderTop(XSSFCellStyle.BORDER_THIN);style.setAlignment(XSSFCellStyle.ALIGN_CENTER);// 生成一个字体XSSFFont font = workbook.createFont();font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);font.setFontName("宋体");font.setColor(new XSSFColor(java.awt.Color.BLACK));font.setFontHeightInPoints((short) 11);// 把字体应用到当前的样式style.setFont(font);// 生成并设置另一个样式XSSFCellStyle style2 = workbook.createCellStyle();style2.setFillForegroundColor(new XSSFColor(java.awt.Color.WHITE));style2.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);style2.setBorderBottom(XSSFCellStyle.BORDER_THIN);style2.setBorderLeft(XSSFCellStyle.BORDER_THIN);style2.setBorderRight(XSSFCellStyle.BORDER_THIN);style2.setBorderTop(XSSFCellStyle.BORDER_THIN);style2.setAlignment(XSSFCellStyle.ALIGN_CENTER);style2.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);// 生成另一个字体XSSFFont font2 = workbook.createFont();font2.setBoldweight(XSSFFont.BOLDWEIGHT_NORMAL);// 把字体应用到当前的样式style2.setFont(font2);// 定义一个数组,存放最大列宽int[] maxColumn = new int[headers.length];// 产生表格标题行XSSFRow row = sheet.createRow(0);XSSFCell cellHeader;for (int i = 0; i < headers.length; i++) {cellHeader = row.createCell(i);cellHeader.setCellStyle(style);cellHeader.setCellValue(new XSSFRichTextString(headers[i]));// 给最大列宽赋初值maxColumn[i] = headers[i].getBytes().length * 256 + 512;}// 遍历集合数据,产生数据行Iterator<T> it = dataset.iterator();int index = 0;T t;Field[] fields;Field field;XSSFRichTextString richString;Pattern p = Pattern.compile("^//d+(//.//d+)?$");Matcher matcher;String fieldName;String getMethodName;XSSFCell cell;Class tCls;Method getMethod;Object value;String textValue;SimpleDateFormat sdf = new SimpleDateFormat(pattern);while (it.hasNext()) {index++;row = sheet.createRow(index);t = (T) it.next();if (t instanceof Map) {int i = 0;for (Map.Entry<String, Object> entry : ((Map<String, Object>)t).entrySet()) {cell = row.createCell(i);cell.setCellStyle(style2);value = entry.getValue();// 判断值的类型后进行强制类型转换textValue = null;if (value instanceof Integer) {cell.setCellValue((Integer) value);} else if (value instanceof Float) {textValue = String.valueOf((Float) value);cell.setCellValue(textValue);} else if (value instanceof Double) {textValue = String.valueOf((Double) value);cell.setCellValue(textValue);} else if (value instanceof Long) {cell.setCellValue((Long) value);}else if (value instanceof Boolean) {textValue = "是";if (!(Boolean) value) {textValue = "否";}} else if (value instanceof Date) {textValue = sdf.format((Date) value);} else {// 其它数据类型都当作字符串简单处理if (value != null) {textValue = value.toString();}}if (textValue != null) {matcher = p.matcher(textValue);if (matcher.matches()) {// 是数字当作double处理cell.setCellValue(Double.parseDouble(textValue));} else {richString = new XSSFRichTextString(textValue);cell.setCellValue(richString);}}// 设置最大列宽,默认20int temp = 20;if (textValue != null) {temp = textValue.getBytes(StandardCharsets.UTF_8).length * 256 + 512;}maxColumn[i] = Math.max(maxColumn[i], temp);i ++;}continue;}// 利用反射,根据JavaBean属性的先后顺序,动态调用getXxx()方法得到属性值fields = t.getClass().getDeclaredFields();for (int i = 0; i < fields.length; i++) {cell = row.createCell(i);cell.setCellStyle(style2);field = fields[i];fieldName = field.getName();getMethodName = "get" + fieldName.substring(0, 1).toUpperCase()+ fieldName.substring(1);try {tCls = t.getClass();getMethod = tCls.getMethod(getMethodName, new Class[] {});value = getMethod.invoke(t, new Object[] {});// 判断值的类型后进行强制类型转换textValue = null;if (value instanceof Integer) {cell.setCellValue((Integer) value);} else if (value instanceof Float) {textValue = String.valueOf((Float) value);cell.setCellValue(textValue);} else if (value instanceof Double) {textValue = String.valueOf((Double) value);cell.setCellValue(textValue);} else if (value instanceof Long) {cell.setCellValue((Long) value);}else if (value instanceof Boolean) {textValue = "是";if (!(Boolean) value) {textValue = "否";}} else if (value instanceof Date) {textValue = sdf.format((Date) value);} else {// 其它数据类型都当作字符串简单处理if (value != null) {textValue = value.toString();}}if (textValue != null) {matcher = p.matcher(textValue);if (matcher.matches()) {// 是数字当作double处理cell.setCellValue(Double.parseDouble(textValue));} else {richString = new XSSFRichTextString(textValue);cell.setCellValue(richString);}}// 设置最大列宽,默认20int temp = 20;if (textValue != null) {temp = textValue.getBytes(StandardCharsets.UTF_8).length * 256 + 512;}maxColumn[i] = Math.max(maxColumn[i], temp);} catch (Exception e) {e.printStackTrace();}}}// 设置自动列宽for (int i = 0; i < maxColumn.length; i++) {sheet.setColumnWidth(i, maxColumn[i]); //调整列宽}/*try {String date = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());String sFileName = date + ".xlsx";response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setHeader("Content-Disposition", "attachment;filename=" + sFileName);response.setHeader("Connection", "close");workbook.write(response.getOutputStream());} catch (Exception e) {e.printStackTrace();}*/}/***  统一写入数据* @param workbook* @param response*/public void write(XSSFWorkbook workbook,  HttpServletResponse response){try {String date = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());String sFileName = date + ".xlsx";response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setHeader("Content-Disposition", "attachment;filename=" + sFileName);response.setHeader("Connection", "close");workbook.write(response.getOutputStream());} catch (Exception e) {e.printStackTrace();}}/*** <p>* 通用Excel导出方法,利用反射机制遍历对象的所有字段,将数据写入Excel文件中 <br>* 此方法生成2003版本的excel,文件名后缀:xls <br>* </p>** @param title*            表格标题名* @param headers*            表格头部标题集合* @param dataset*            需要显示的数据集合,集合中一定要放置符合JavaBean风格的类的对象。此方法支持的*            JavaBean属性的数据类型有基本数据类型及String,Date* @param response*            与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中* @param pattern*            如果有时间数据,设定输出格式。默认为"yyyy-MM-dd hh:mm:ss"*/@SuppressWarnings({ "unchecked", "rawtypes" })private void exportExcel2003(String title, String[] headers, Collection<T> dataset, HttpServletRequest request, HttpServletResponse response, String pattern, int sheetNum) {// 声明一个工作薄HSSFWorkbook workbook = new HSSFWorkbook();// 生成一个表格HSSFSheet sheet = workbook.createSheet(title);workbook.setSheetName(sheetNum, title);// 设置表格默认列宽度为15个字节sheet.setDefaultColumnWidth(20);// 生成一个样式HSSFCellStyle style = workbook.createCellStyle();// 设置这些样式style.setFillForegroundColor(HSSFColor.GREY_50_PERCENT.index);style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);style.setBorderBottom(HSSFCellStyle.BORDER_THIN);style.setBorderLeft(HSSFCellStyle.BORDER_THIN);style.setBorderRight(HSSFCellStyle.BORDER_THIN);style.setBorderTop(HSSFCellStyle.BORDER_THIN);style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 生成一个字体HSSFFont font = workbook.createFont();font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);font.setFontName("宋体");font.setColor(HSSFColor.WHITE.index);font.setFontHeightInPoints((short) 11);// 把字体应用到当前的样式style.setFont(font);// 生成并设置另一个样式HSSFCellStyle style2 = workbook.createCellStyle();style2.setFillForegroundColor(HSSFColor.WHITE.index);style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);style2.setBorderRight(HSSFCellStyle.BORDER_THIN);style2.setBorderTop(HSSFCellStyle.BORDER_THIN);style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 生成另一个字体HSSFFont font2 = workbook.createFont();font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);// 把字体应用到当前的样式style2.setFont(font2);// 定义一个数组,存放最大列宽int[] maxColumn = new int[headers.length];// 产生表格标题行HSSFRow row = sheet.createRow(0);HSSFCell cellHeader;for (int i = 0; i < headers.length; i++) {cellHeader = row.createCell(i);cellHeader.setCellStyle(style);cellHeader.setCellValue(new HSSFRichTextString(headers[i]));// 给最大列宽赋初值maxColumn[i] = headers[i].getBytes().length * 256 + 512;}// 遍历集合数据,产生数据行Iterator<T> it = dataset.iterator();int index = 0;T t;Field[] fields;Field field;HSSFRichTextString richString;Pattern p = Pattern.compile("^//d+(//.//d+)?$");Matcher matcher;String fieldName;String getMethodName;HSSFCell cell;Class tCls;Method getMethod;Object value;String textValue;SimpleDateFormat sdf = new SimpleDateFormat(pattern);while (it.hasNext()) {index++;row = sheet.createRow(index);t = (T) it.next();// 利用反射,根据JavaBean属性的先后顺序,动态调用getXxx()方法得到属性值fields = t.getClass().getDeclaredFields();for (int i = 0; i < fields.length; i++) {cell = row.createCell(i);cell.setCellStyle(style2);field = fields[i];fieldName = field.getName();getMethodName = "get" + fieldName.substring(0, 1).toUpperCase()+ fieldName.substring(1);try {tCls = t.getClass();getMethod = tCls.getMethod(getMethodName, new Class[] {});value = getMethod.invoke(t, new Object[] {});// 判断值的类型后进行强制类型转换textValue = null;if (value instanceof Integer) {cell.setCellValue((Integer) value);} else if (value instanceof Float) {textValue = String.valueOf((Float) value);cell.setCellValue(textValue);} else if (value instanceof Double) {textValue = String.valueOf((Double) value);cell.setCellValue(textValue);} else if (value instanceof Long) {cell.setCellValue((Long) value);}if (value instanceof Boolean) {textValue = "是";if (!(Boolean) value) {textValue = "否";}} else if (value instanceof Date) {textValue = sdf.format((Date) value);} else {// 其它数据类型都当作字符串简单处理if (value != null) {textValue = value.toString();}}if (textValue != null) {matcher = p.matcher(textValue);if (matcher.matches()) {// 是数字当作double处理cell.setCellValue(Double.parseDouble(textValue));} else {richString = new HSSFRichTextString(textValue);cell.setCellValue(richString);}}// 设置最大列宽,默认20int temp = 20;if (textValue != null) {temp = textValue.getBytes(StandardCharsets.UTF_8).length * 256 + 512;}maxColumn[i] = Math.max(maxColumn[i], temp);} catch (Exception e) {e.printStackTrace();}}}// 设置自动列宽for (int i = 0; i < maxColumn.length; i++) {sheet.setColumnWidth(i, maxColumn[i]); //调整列宽}try {String date = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());String sFileName = date + ".xls";response.setContentType("application/vnd.ms-excel");response.setHeader("Content-Disposition", "attachment;filename=" + sFileName);response.setHeader("Connection", "close");workbook.write(response.getOutputStream());} catch (IOException e) {e.printStackTrace();}}}

三、项目中使用

    /*** @Description 导出农机销售信息* @Author Ldpy* @Date 2020/9/1 16:30* @param req 统一参数 (此处进行了本地封装,自己用可以用常规表单传值即可)* @throws Exception*/@PostMapping("/exportMachineStatis")public void exportSubsidyMachineStatis(Req req, HttpServletRequest request, HttpServletResponse response) throws Exception {List<MachineNumVO> list = subscriberDtIotPurchaseSubsidyService.getMachineNumAndSubsidy(req);List<MachineNumVO> subList = subscriberDtIotPurchaseSubsidyService.getMachineNumAndSubsidyForCounty(req);List<MachineDetailVO> detailList = subscriberDtIotPurchaseSubsidyService.getMachineNumAndSubsidyForDetail(req);String fileName1 = "按省统计";String fileName2 = "按县统计";String fileName3 = "详情信息";// 表头数组1String[] hearders1 = new String[]{"地区","机具品目","拖拉机数量(台)","购买金额(万元)","购机资金总额(万元)","表头字段名"};// 表头数组2String[] hearders2 = new String[]{"表头字段名","表头字段名","表头字段名","表头字段名","表头字段名","表头字段名"};// 表头数组3String[] hearders3 = new String[]{"表头字段名","表头字段名","表头字段名","表头字段名","表头字段名","表头字段名"};//调用Excel工具类ExportExcelUtil ex = new ExportExcelUtil();XSSFWorkbook workbook = new XSSFWorkbook();try {ex.exportExcel(workbook, fileName1, hearders1, list, request, response, "2007", 0);ex.exportExcel(workbook, fileName2, hearders2, subList, request, response, "2007", 1);ex.exportExcel(workbook, fileName3, hearders3, detailList, request, response, "2007", 2);ex.write(workbook, response);} catch (Exception e) {e.printStackTrace();}}

实体类(其余两个实体类省略,根据自己的业务自行编写),注意:表头与实体类中的字段是一一对应的关系!如果使用Map,必须返回LinkedHashMap,这样值才能与表头匹配。

package com.xxx.xxx.entity;public class MachineNumVO {/*** 地区*/private String subAddress;/*** 机具品目*/private String njName;/*** 拖拉机数量(台)*/private String njNum;/*** 购买金额(万元)*/private String centralSubsidy;/*** 购机资金总额(万元)*/private String buyPrice;/*** 表头字段名*/private String acreage;public String getSubAddress() {return subAddress;}public void setSubAddress(String subAddress) {this.subAddress = subAddress;}public String getNjName() {return njName;}public void setNjName(String njName) {this.njName = njName;}public String getNjNum() {return njNum;}public void setNjNum(String njNum) {this.njNum = njNum;}public String getCentralSubsidy() {return centralSubsidy;}public void setCentralSubsidy(String centralSubsidy) {this.centralSubsidy = centralSubsidy;}public String getBuyPrice() {return buyPrice;}public void setBuyPrice(String buyPrice) {this.buyPrice = buyPrice;}public String getAcreage() {return acreage;}public void setAcreage(String acreage) {this.acreage = acreage;}
}

四、最后效果

Excel导出工具类相关推荐

  1. Java之Excel导出工具类使用教程

    前言: 本工具类经过PostMan和web页面严格测试可用,经过了多个版本迭代优化,可以直接使用,也方便大家根据自己的业务需求,修改定制自己的导出工具. 市面上有很多封装好的导出工具(如:阿里的eas ...

  2. 自己写的java excel导出工具类

    最近项目要用到excel导出功能,之前也写过类似的代码.因为这次项目中多次用到excel导出.这次长了记性整理了一下 分享给大伙 欢迎一起讨论 生成excel的主工具类: public class E ...

  3. java Excel导出工具类

    Excel工具类 一.开发原因 最近工作的时候,正在写关于Excel导出功能,由于当前使用的工具类不太灵活和不易看懂,自己从头写又很浪费时间等原因,我决定自己写一款很简单的Excel导出的工具类,仅仅 ...

  4. Poi excel 导出 工具类参考

    public void poiCreateExcel(HttpServletResponse response, Map<String, Object> map) {// 下载文件信息St ...

  5. esayExcel导出工具类

    依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artif ...

  6. javaExcel 导出(基于POI的复杂表格导出工具类)

    我的需求: 项目中有一些工程表格需要导出,设计到行列合并,定制样式,原有工具类冗余,内聚性强.所以想写一个可以随意定制excel的工具类,工具类满足需求: 对于常用的工程表格有模板格式,可以任意插拔. ...

  7. 一个基于POI的通用excel导入导出工具类的简单实现及使用方法

    前言: 最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据.网上关于excel导入导出的例子很多,但大多相互借鉴. ...

  8. java Excel导入导出工具类 及使用demo

    java Excel导入导出工具类 及使用demo 前言:相信进来的都是想尽快解决问题的,话不多说,按照以下步骤来,可以操作导出excel到本地,导入同理,自行学习.步骤一:直接复制以下excel工具 ...

  9. Java操作百万数据量Excel导入导出工具类(程序代码教程)

    Java操作百万数据量Excel导入导出工具类(程序代码教程): # 功能实现1.自定义导入数据格式,支持配置时间.小数点类型(支持单/多sheet)(2种方式:本地文件路径导入(只支持xls.xls ...

最新文章

  1. (4)段描述符P,G位
  2. matlab最小生成树举例,Matlab最小生成树示例
  3. selenium--特殊元素定位
  4. appium示例代码python_appium+Python 脚本编写
  5. [Android] AudioEffect架构:从上层调用到底层音效驱动
  6. Java项目:药品管理系统(java+SSM+html+jQuery+Tomcat+mysql)
  7. 从0到1手写分布式对象存储系统-05纠删码与数据修复
  8. 初学者用什么数位板好,手绘板选择注意什么?
  9. 联想电脑预装office自动卸载工具
  10. [维修案例] 艾美特电风扇(FS4085R)不能调风量维修
  11. 白话Istio—流量管理四大概念
  12. 计算机网络 - NB-IOT/LoRa/Zigbee 无线组网方案对比
  13. 重建windows系统的引导盘(亲测可用)
  14. 用友GRP-U8Cloud V11.0 V11.21 行政业务高校 G C版
  15. 大数据开发——Hive实战案例
  16. 《使用MAVEN+SSM+Ajax+shiro+MySql开发在线商场详解(4)》
  17. 解决audio控制播放音量
  18. P1936 水晶灯火灵
  19. RecyclerView 复用错乱通用解法
  20. 2023(19届) 软件工程毕业设计选题推荐(二)

热门文章

  1. 小米8刷入Magisk24.0并安装riru和EdXposed之刷机篇
  2. 过宝塔php大马,分享宝塔网站防火墙使用帮助
  3. CSS3学习笔记三---怪异盒模型 | 弹性盒*
  4. 485传感器接入串口交换机采集方案
  5. 末日启示:向死而生--《罗辑思维》第一季第一期
  6. 前端工程化----Node.js基础篇
  7. 【读书笔记】《结构思考力》——李忠秋
  8. 学python最重要的是什么_学Python之前,什么最重要?
  9. oracle 表空间转换,Oracle表空间数据文件移动的方法
  10. 互联网日报 | 5月14日 星期五 | “辣条一哥”卫龙将赴港上市;B站付费用户破2000万;京东物流预计5月28日在港上市...