赞
踩
先导入依赖:
- <!-- 文件上传 -->
- <dependency>
- <groupId>org.apache.httpcomponents</groupId>
- <artifactId>httpmime</artifactId>
- <version>4.5.7</version>
- </dependency>
- <!-- JSON -->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>fastjson</artifactId>
- <version>1.2.41</version>
- </dependency>
- <!-- POI -->
- <dependency>
- <groupId>org.apache.poi</groupId>
- <artifactId>poi-ooxml</artifactId>
- <version>3.16</version>
- </dependency>
1、获取想要上传excel文件的路径
2、获得路径后,通过路径定位生成数据流,使用FileInputStream方法读取路径对应文件的原始字节流。
- //根据路径生成 FileInputStream字节流
- FileInputStream inputStream = new FileInputStream(new File(fileName));
3、使用ExcelUtils工具类读取 字节流 + 路径。
- //通过ExcelUtils工具将Excel数据存入到list中,工具代码下面细讲,这一步读取Excel已经完成了,如果不想进行插入数据库操作,可以直接拿着list用啦。
- List<List<Object>> list = ExcelUtils.getListByExcel(inputStream,fileName);
4、ExcelUtils工具类对数据进行处理,因为表格有行和列,所以处理完数据使用二维集合List<List>对数据进行存储。
ExcelUtils类讲解:
- public class ExcelUtils {
- private final static String excel2003L =".xls"; //2003- 版本的excel
- private final static String excel2007U =".xlsx"; //2007版本
-
- /**
- * @Description:获取IO流中的数据,组装成List<List<Object>>对象
- * @param in,fileName
- * @return
- * @throws
- */
- public static List<List<Object>> getListByExcel(InputStream in, String fileName) throws Exception{
- List<List<Object>> list = null;
- //创建Excel工作薄
- Workbook work = getWorkbook(in,fileName);
- if(null == work){
- throw new Exception("创建Excel工作薄为空!");
- }
- Sheet sheet = null; //页数
- Row row = null; //行数
- Cell cell = null; //列数
-
- list = new ArrayList<List<Object>>();
- //遍历Excel中所有的sheet
- for (int i = 0; i < work.getNumberOfSheets(); i++) {
- sheet = work.getSheetAt(i);
- if(sheet==null){continue;}
-
- //遍历当前sheet中的所有行
- for (int j = sheet.getFirstRowNum(); j <= sheet.getLastRowNum(); j++) {
- row = sheet.getRow(j);
- if(row==null){continue;}
-
- //遍历所有的列
- List<Object> li = new ArrayList<Object>();
- for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {
- cell = row.getCell(y);
- li.add(getValue(cell));
- }
- list.add(li);
- }
- }
-
- return list;
-
- }
-
- /**
- * @Description:根据文件后缀,自适应上传文件的版本
- * @param inStr,fileName
- * @return
- * @throws Exception
- */
- public static Workbook getWorkbook(InputStream inStr,String fileName) throws Exception{
- Workbook wb = null;
- String fileType = fileName.substring(fileName.lastIndexOf("."));
- if(excel2003L.equals(fileType)){
- wb = new HSSFWorkbook(inStr); //2003-
- }else if(excel2007U.equals(fileType)){
- wb = new XSSFWorkbook(inStr); //2007+
- }else{
- throw new Exception("解析的文件格式有误!");
- }
- return wb;
- }
-
- /**
- * @Description:对表格中数值进行格式化
- * @param cell
- * @return
- */
- //解决excel类型问题,获得数值
- public static String getValue(Cell cell) {
- String value = "";
- if(null==cell){
- return value;
- }
- switch (cell.getCellType()) {
- //数值型
- case NUMERIC:
- if (DateUtil.isCellDateFormatted(cell)) {
- //如果是date类型则 ,获取该cell的date值
- Date date = DateUtil.getJavaDate(cell.getNumericCellValue());
- SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
- value = format.format(date);;
- }else {// 纯数字
- BigDecimal big=new BigDecimal(cell.getNumericCellValue());
- value = big.toString();
- //解决1234.0 去掉后面的.0
- if(null!=value&&!"".equals(value.trim())){
- String[] item = value.split("[.]");
- if(1<item.length&&"0".equals(item[1])){
- value=item[0];
- }
- }
- }
- break;
- //字符串类型
- case STRING:
- value = cell.getStringCellValue();
- break;
- // 公式类型
- case FORMULA:
- //读公式计算值
- value = String.valueOf(cell.getNumericCellValue());
- if (value.equals("NaN")) {// 如果获取的数据值为非法值,则转换为获取字符串
- value = cell.getStringCellValue();
- }
- break;
- // 布尔类型
- case BOOLEAN:
- value = " "+ cell.getBooleanCellValue();
- break;
- default:
- value = cell.getStringCellValue();
- }
- if("null".endsWith(value.trim())){
- value="";
- }
- return value;
- }
- }
5、已经获取到了Excel表格中所有的数据,包含所有的行和列,都在List<List>中,这一步所有的数据获取完了
6、有了数据,要将数据存储到数据库。
7、需要创建数据库字段的实体类,使用@Excel注解将表格和数据库字段名一一对应
- @Data
- @TableName("t_student")//数据库名字
- public class Student{
-
- @TableId(type = IdType.AUTO)
- @Excel(name = "序号", cellType = Excel.ColumnType.NUMERIC)
- private Long id;
-
- @Excel(name = "学生ID")
- private Long id;
-
- @Excel(name = "名称")
- private String name;
-
- @Excel(name = "性别")
- private String sex;
-
- @Excel(name = "年龄")
- private String age;
-
-
-
- }
8、通过双重 for循环遍历List<List>,内层List为列,外层List为行,如下图将第一行数据单独拿出来,作为判断字段,如果实体类等@Excel注解属性和Excel表格第一行名字相同,对实体类进行set赋值
- //定义Excel第一行的属性
- List<Object> firstRows = null;
- //获取第一行属性 放入firstRows中。
- if(list != null && list.size() > 0){
- firstRows = list.get(0);
- }
- //遍历除第一行以外的Excel表格中的值
- for (int i = 1; i < list.size(); i++) {
- //rows是某一行,i = 1 为第二行, i = 2 为第三行
- List<Object> rows = list.get(i);
- //数据库数据的实体类
- Student student =new student();
- //遍历这一行所有的值
- for (int j = 0; j < rows.size(); j++){
- //某一行的某一列 j为列的坐标
- String cellVal = (String) rows.get(j);
- //对实体类进行赋值,使用setFieldValueByFieldName方法,下面详细讲代码
- TestExcel.setFieldValueByFieldName(questionBank, firstRows.get(j).toString().trim(), cellVal);
- }
-
- }
- // 使用spring插入到数据库
- questionBankService.save(questionBank);
- }
9、从第二行开始,每遍历完一行,将获得一个实体类对象,因为是结合数据库写的实体类,通过springboot可以直接插入数据库。
- public class TestExcel {
-
- /**
- * 用反射方法,获取列名,比较,为属性赋值
- * @param object
- * @param fieldName
- * @param val
- */
- public static void setFieldValueByFieldName(Object object, String fieldName, Object val) {
- try {
- //通过反射获取所有实体类所有定义的方法,object为数据库实体类
- Field[] fields = object.getClass().getDeclaredFields();
- //遍历fields
- for (int i = 0; i < fields.length; i++) {
- Field field = fields[i];
- //读取注释,如@Excel(name = "科目")
- Excel annotation = field.getAnnotation(Excel.class);
- //因为private类型,所有要设置允许
- field.setAccessible(true);
- //annotation.name() 注解里的属性,如果annotation没写注解,读取原始名字如subject
- if(annotation == null){
- if(fieldName.equals(field.getName())){
- if(field.getType() == Integer.class){
- field.set(object, Integer.valueOf(val.toString()));
- }else if(field.getType() == Long.class){
- field.set(object, Long.valueOf(val.toString()));
- }else {
- field.set(object, val);
- }
- return;
- }
- }else {//设置了注解,并且表格里的Excel字段值和注解的name值相同,则为相应字段赋值
- if(fieldName.equals(annotation.name())){
- //进行类型判断,因为实体类中变量类型不同。
- if(field.getType() == Integer.class){
- field.set(object, Integer.valueOf(val.toString()));
- }else if(field.getType() == Long.class){
- field.set(object, Long.valueOf(val.toString()));
- }else {
- field.set(object, val);
- }
- return;
- }
- }
-
- }
- }catch (Exception e){
- e.printStackTrace();
- }
- }
-
- }
六、通用读取excel工具类
- package com.ssm;
-
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.InputStream;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
-
- import org.apache.poi.hssf.usermodel.HSSFCell;
- 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.ss.usermodel.CellType;
- import org.apache.poi.xssf.usermodel.XSSFCell;
- import org.apache.poi.xssf.usermodel.XSSFRow;
- import org.apache.poi.xssf.usermodel.XSSFSheet;
- import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-
- public class ReadExcel {
-
- public List<Map<String,String>> readExcel(String filepath, String filename, int startrow, int startcol, int sheetnum) {
- List<Map<String, String>> varList = new ArrayList<Map<String, String>>();
- String suffix = filename.substring(filename.lastIndexOf(".") + 1);
- if ("xls".equals(suffix)) {
- varList = readExcel2003(filepath, filename, startrow, startcol, sheetnum);
- } else if ("xlsx".equals(suffix)) {
- varList = readExcel2007(filepath, filename, startrow, startcol, sheetnum);
- } else {
- System.out.println("Only excel files with XLS or XLSX suffixes are allowed to be read!");
- return null;
- }
- return varList;
- }
-
-
-
- /**
- * 读取2003Excel
- *
- * @param filepath 文件路径
- * @param filename 文件名,包括扩展名
- * @param startrow 开始行号,索引从0开始
- * @param startcol 开始列号,索引从0开始
- * @param sheetnum 工作簿,索引从0开始
- * @return
- */
- public static List<Map<String,String>> readExcel2003(String filepath, String filename, int startrow, int startcol, int sheetnum) {
- List<Map<String, String>> varList = new ArrayList<Map<String, String>>();
- try {
- File target = new File(filepath, filename);
- FileInputStream fis = new FileInputStream(target);
- HSSFWorkbook wb = new HSSFWorkbook(fis);
- fis.close();
- // sheet 从0开始
- HSSFSheet sheet = wb.getSheetAt(sheetnum);
- // 取得最后一行的行号
- int rowNum = sheet.getLastRowNum() + 1;
-
- HSSFRow rowTitle = sheet.getRow(0);
- // 标题行的最后一个单元格位置
- int cellTitleNum = rowTitle.getLastCellNum();
- String[] title = new String[cellTitleNum];
- for (int i = startcol; i < cellTitleNum; i++) {
- HSSFCell cell = rowTitle.getCell(Short.parseShort(i + ""));
- if (cell != null) {
- cell.setCellType(CellType.STRING);
- title[i] = cell.getStringCellValue();
- } else {
- title[i] = "";
- }
- }
-
- // 行循环开始
- for (int i = startrow + 1; i < rowNum; i++) {
- Map<String, String> varpd = new HashMap<String, String>();
- // 行
- HSSFRow row = sheet.getRow(i);
- // 列循环开始
- for (int j = startcol; j < cellTitleNum; j++) {
-
- HSSFCell cell = row.getCell(Short.parseShort(j + ""));
- String cellValue = "";
- if (cell != null) {
- // 把类型先设置为字符串类型
- cell.setCellType(CellType.STRING);
- cellValue = cell.getStringCellValue();
- }
- varpd.put(title[j], cellValue);
- }
- varList.add(varpd);
- }
- wb.close();
- } catch (Exception e) {
- System.out.println(e);
- }
- return varList;
- }
-
- /**
- * 读取2007Excel
- *
- * @param filepath 文件路径
- * @param filename 文件名,包括扩展名
- * @param startrow 开始行号,索引从0开始
- * @param startcol 开始列号,索引从0开始
- * @param sheetnum 工作簿,索引从0开始
- * @return
- */
- public List<Map<String,String>> readExcel2007(String filepath, String filename, int startrow, int startcol, int sheetnum) {
- List<Map<String, String>> varList = new ArrayList<Map<String, String>>();
- try {
- File target = new File(filepath, filename);
- InputStream ins = new FileInputStream(target);
- XSSFWorkbook wb = new XSSFWorkbook(ins);
- ins.close();
- // 得到Excel工作表对象
- XSSFSheet sheet = wb.getSheetAt(sheetnum);
- // 取得最后一行的行号
- int rowNum = sheet.getLastRowNum() + 1;
-
- XSSFRow rowTitle = sheet.getRow(0);
- int cellTitleNum = rowTitle.getLastCellNum();
- String[] title = new String[cellTitleNum];
- for (int i = startcol; i < cellTitleNum; i++) {
- XSSFCell cell = rowTitle.getCell(Short.parseShort(i + ""));
- if (cell != null) {
- // 把类型先设置为字符串类型
- cell.setCellType(CellType.STRING);
- title[i] = cell.getStringCellValue();
- } else {
- title[i] = "";
- }
- }
-
- // 行循环开始
- for (int i = startrow + 1; i < rowNum; i++) {
- Map<String, String> varpd = new HashMap<String, String>();
- // 得到Excel工作表的行
- XSSFRow row = sheet.getRow(i);
- // 列循环开始
- for (int j = startcol; j < cellTitleNum; j++) {
- // 得到Excel工作表指定行的单元格
- XSSFCell cell = row.getCell(j);
- String cellValue = "";
- if (cell != null) {
- // 把类型先设置为字符串类型
- cell.setCellType(CellType.STRING);
- cellValue = cell.getStringCellValue();
- }
- varpd.put(title[j], cellValue);
- }
- varList.add(varpd);
- }
- wb.close();
- } catch (Exception e) {
- System.out.println(e);
- }
- return varList;
- }
-
-
-
-
-
-
-
-
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。