SpringBoot项目Java实现Excel文件上传数据解析和Excel文件导出

java实现Excel文件导入导出网上有很多方法,比如:
通过POI实现Excel文件导入导出,
使用java Excel操作Excel文件,
或者使用 JXL实现读写Excel等等。

我这里自己总结以下比较简单常用的通过POI实现Excel文件读写导入导出功能
POI优点:效率搞,支持的应用广泛,操作属性丰富等优点,也较易上手。
本次我总结的内容可以同时支持.xlsx和.xls两种Excel格式

首先你的项目需要在pom文件配置依赖包

<!-- 读取后缀为xlsx或xls的excel操作需要导入包 -->
		<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>

在项目中创建一个Util包,然后将以下两个ExcelUtil和ReadExcelUtil操作Excel的Util类放进去:
这是我的包目录:
SpringBoot项目Java实现Excel文件上传数据解析和Excel文件导出_第1张图片
ExcelUtil 类:

public class ExcelUtil {
     
    private static final Logger logger = Logger.getLogger(ExcelUtil.class);
    public static final String OFFICE_EXCEL_2003_POSTFIX = "xls";
    public static final String OFFICE_EXCEL_2010_POSTFIX = "xlsx";
    public static final String EMPTY = "";
    public static final String POINT = ".";
    public static SimpleDateFormat sdf =   new SimpleDateFormat("yyyy/MM/dd");

    /**
     * 获得path的后缀名
     * @param path
     * @return
     */
    public static String getPostfix(String path){
     
        if(path==null || EMPTY.equals(path.trim())){
     
            return EMPTY;
        }
        if(path.contains(POINT)){
     
            return path.substring(path.lastIndexOf(POINT)+1,path.length());
        }
        return EMPTY;
    }
    /**
     * 单元格格式
     * @param hssfCell
     * @return
     */
    @SuppressWarnings({
      "static-access", "deprecation" })
    public static String getHValue(HSSFCell hssfCell){
     
        if (hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN) {
     
            return String.valueOf(hssfCell.getBooleanCellValue());
        } else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC) {
     
            String cellValue = "";
            if(HSSFDateUtil.isCellDateFormatted(hssfCell)){
     
                Date date = HSSFDateUtil.getJavaDate(hssfCell.getNumericCellValue());
                cellValue = sdf.format(date);
            }else{
     
                DecimalFormat df = new DecimalFormat("#.##");
                cellValue = df.format(hssfCell.getNumericCellValue());
                String strArr = cellValue.substring(cellValue.lastIndexOf(POINT)+1,cellValue.length());
                if(strArr.equals("00")){
     
                    cellValue = cellValue.substring(0, cellValue.lastIndexOf(POINT));
                }
            }
            return cellValue;
        } else {
     
            return String.valueOf(hssfCell.getStringCellValue());
        }
    }
    /**
     * 单元格格式
     * @param xssfCell
     * @return
     */
    public static String getXValue(XSSFCell xssfCell){
     
        if (xssfCell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
     
            return String.valueOf(xssfCell.getBooleanCellValue());
        } else if (xssfCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
     
            String cellValue = "";
            if(XSSFDateUtil.isCellDateFormatted(xssfCell)){
     
                Date date = XSSFDateUtil.getJavaDate(xssfCell.getNumericCellValue());
                cellValue = sdf.format(date);
            }else{
     
                DecimalFormat df = new DecimalFormat("#.##");
                cellValue = df.format(xssfCell.getNumericCellValue());
                String strArr = cellValue.substring(cellValue.lastIndexOf(POINT)+1,cellValue.length());
                if(strArr.equals("00")){
     
                    cellValue = cellValue.substring(0, cellValue.lastIndexOf(POINT));
                }
            }
            return cellValue;
        } else {
     
            return String.valueOf(xssfCell.getStringCellValue());
        }
    }
    /**
     * 自定义xssf日期工具类
     * 
     */
    static class XSSFDateUtil extends DateUtil {
     
        protected static int absoluteDay(Calendar cal, boolean use1904windowing) {
     
            return DateUtil.absoluteDay(cal, use1904windowing);
        }
    }
}

ReadExcelUtil 类:

public class ReadExcelUtil {
     
    public int totalRows; //sheet中总行数
    public static int totalCells; //每一行总单元格数
    /**
     * read the Excel .xlsx,.xls
     * @param file jsp中的上传文件
     * @return
     * @throws IOException
     */
    public List<ArrayList<String>> readExcel(MultipartFile file) throws IOException {
     
        if(file==null||ExcelUtil.EMPTY.equals(file.getOriginalFilename().trim())){
     
            return null;
        }else{
     
            String postfix = ExcelUtil.getPostfix(file.getOriginalFilename());
            if(!ExcelUtil.EMPTY.equals(postfix)){
     
                if(ExcelUtil.OFFICE_EXCEL_2003_POSTFIX.equals(postfix)){
     
                    return readXls(file);
                }else if(ExcelUtil.OFFICE_EXCEL_2010_POSTFIX.equals(postfix)){
     
                    return readXlsx(file);
                }else{
     
                    return null;
                }
            }
        }
        return null;
    }
    /**
     * read the Excel 2010 .xlsx
     * @param file
     * @return
     * @throws IOException
     */
    @SuppressWarnings("deprecation")
    public List<ArrayList<String>> readXlsx(MultipartFile file){
     
        List<ArrayList<String>> list = new ArrayList<ArrayList<String>>();
        // IO流读取文件
        InputStream input = null;
        XSSFWorkbook wb = null;
        ArrayList<String> rowList = null;
        try {
     
            input = file.getInputStream();
            // 创建文档
            wb = new XSSFWorkbook(input);
            //读取sheet(页)
            for(int numSheet=0;numSheet<wb.getNumberOfSheets();numSheet++){
     
                XSSFSheet xssfSheet = wb.getSheetAt(numSheet);
                if(xssfSheet == null){
     
                    continue;
                }
                totalRows = xssfSheet.getLastRowNum();
                //读取Row,从第4行开始
                for(int rowNum = 1;rowNum <= totalRows;rowNum++){
     
                    XSSFRow xssfRow = xssfSheet.getRow(rowNum);
                    if(xssfRow!=null){
     
                        rowList = new ArrayList<String>();
                        totalCells = xssfRow.getLastCellNum();
                        //读取列,从第一列开始
                        for(int c=0;c<=totalCells+1;c++){
     
                            XSSFCell cell = xssfRow.getCell(c);
                            if(cell==null){
     
                                rowList.add(ExcelUtil.EMPTY);
                                continue;
                            }
                            rowList.add(ExcelUtil.getXValue(cell).trim());
                        }
                        list.add(rowList);
                    }
                }
            }
            return list;
        } catch (IOException e) {
     
            e.printStackTrace();
        } finally{
     
            try {
     
                input.close();
            } catch (IOException e) {
     
                e.printStackTrace();
            }
        }
        return null;

    }
    /**
     * read the Excel 2003-2007 .xls
     * @param file
     * @return
     * @throws IOException
     */
    public List<ArrayList<String>> readXls(MultipartFile file){
     
        List<ArrayList<String>> list = new ArrayList<ArrayList<String>>();
        // IO流读取文件
        InputStream input = null;
        HSSFWorkbook wb = null;
        ArrayList<String> rowList = null;
        try {
     
            input = file.getInputStream();
            // 创建文档
            wb = new HSSFWorkbook(input);
            //读取sheet(页)
            for(int numSheet=0;numSheet<wb.getNumberOfSheets();numSheet++){
     
                HSSFSheet hssfSheet = wb.getSheetAt(numSheet);
                if(hssfSheet == null){
     
                    continue;
                }
                totalRows = hssfSheet.getLastRowNum();
                //读取Row,从第二行开始
                for(int rowNum = 1;rowNum <= totalRows;rowNum++){
     
                    HSSFRow hssfRow = hssfSheet.getRow(rowNum);
                    if(hssfRow!=null){
     
                        rowList = new ArrayList<String>();
                        totalCells = hssfRow.getLastCellNum();
                        //读取列,从第一列开始
                        for(short c=0;c<=totalCells+1;c++){
     
                            HSSFCell cell = hssfRow.getCell(c);
                            if(cell==null){
     
                                rowList.add(ExcelUtil.EMPTY);
                                continue;
                            }
                            rowList.add(ExcelUtil.getHValue(cell).trim());
                        }
                        list.add(rowList);
                    }
                }
            }
            return list;
        } catch (IOException e) {
     
            e.printStackTrace();
        } finally{
     
            try {
     
                input.close();
            } catch (IOException e) {
     
                e.printStackTrace();
            }
        }
        return null;
    }
}

Controller层
方法1:获取Excel文件并解析数据
方法2:信息excel数据重新整理导出Excel

@Controller
@RequestMapping("/v1/customer")
public class CustomerInfoController {
     

	private static Logger logger = Logger.getLogger(CustomerInfoController.class);
	
	@Autowired
	private CustomerInfoService customerInfoService;
	
	@ApiOperation(value = "信息excel数据解析导入数据库", notes = "注意事项")
	@RequestMapping(value="/excelImport",method=RequestMethod.POST)
	@ResponseBody
	public ResponseData excelImport(@RequestParam(value="userFile") MultipartFile file,
            HttpServletRequest request) {
     
		List<ArrayList<String>> readExcel = new ArrayList<>();
		try {
     
		 //调用util方法拿到解析的数据集合
			readExcel = new ReadExcelUtil().readExcel(file);
		} catch (IOException e) {
     
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		String originalFileName = file.getOriginalFilename();
		int beginIndex = originalFileName.lastIndexOf(".");
		//原名
		String fileName = originalFileName.substring(0,beginIndex);
		boolean response = customerInfoService.insterCustomerInfo(readExcel, fileName);
		
        if (response) {
     
	        return new ResponseData(SystemCodeConstant.RIGHT_CODE, response, "请求成功");
		}else{
     
            return new ResponseData(SystemCodeConstant.ERROR_CODE, response, SystemErrorConstant.SAVE_ERROR_DESCRIPTION);
		}
	}
	
	@ApiOperation(value = "信息excel数据重新整理导出Excel", notes = "注意事项")
	@RequestMapping(value="/excelExportFile",method=RequestMethod.POST)
	@ResponseBody
	public void excelExportFile(@RequestParam(value="file") MultipartFile file, HttpServletResponse response) {
     
		List<ArrayList<String>> readExcel = new ArrayList<>();
		try {
     
		//调用util方法拿到解析的数据集合
			readExcel = new ReadExcelUtil().readExcel(file);
		} catch (IOException e) {
     
			e.printStackTrace();
		}
		//获取文件名后缀
		String postfix = ExcelUtil.getPostfix(file.getOriginalFilename());
		//获取文件名
		String originalFileName = file.getOriginalFilename();
		int beginIndex = originalFileName.lastIndexOf(".");
		String fileName = originalFileName.substring(0,beginIndex);
		//调用service层业务接口实现Excel文件整理和创建
		Workbook wb = customerInfoService.excelEmportFile(readExcel, fileName, postfix);
		// 响应到客户端
		try {
     
			fileName = fileName + "." + postfix;
			ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
			wb.write(outputStream);
			ByteArrayInputStream tempIn = new ByteArrayInputStream(outputStream.toByteArray());
			response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
			response.setHeader("Content-Length", String.valueOf(tempIn.available()));
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.addHeader("Content-type", "application-download");
            response.setContentType("application/octet-stream");
            ServletOutputStream out = response.getOutputStream();
            BufferedOutputStream toOut = new BufferedOutputStream(out);
	        byte[] buffer = new byte[tempIn.available()];
	        int a;
	        while ((a = tempIn.read(buffer)) != -1) {
     
	            out.write(buffer, 0, a);
	        }
            toOut.write(buffer);
            toOut.flush();
	        out.flush();
	        out.close();
		} catch (Exception e) {
     
			e.printStackTrace();
		}
	}
}

具体的业务操作如下service接口实现:
方法1:将解析的Excel数据集合保存至数据库
方法2:将解析的Excel数据按照业务过滤重复数据重新生成Excel文件返回

@Service
@Transactional
public class CustomerInfoServiceImpl implements CustomerInfoService {
     
	
	@Autowired
	//操作数据库接口
	private CustomerInfoMapper customerInfoMapper;
	
	@Override
	public boolean insterCustomerInfo(List<ArrayList<String>> readExcel, String fileName) {
     
		// 读取数据封装实体
		if(readExcel.size() == 0) {
     
			return false;
		}
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
		
		String sign = fileName+formatter.format(new Date());
		List<CustomerPhoneInfoDo> doList = new ArrayList<>();
		//将解析的Excel数据集合封装到实体,
		for(List<String> sList : readExcel) {
     
			CustomerPhoneInfoDo customerPhoneInfoDo = new CustomerPhoneInfoDo();
			int count = 0;
			for(String str : sList) {
     
				if(0 == count) {
     
					// 客户名称
					customerPhoneInfoDo.setUserName(str==null?"":str.toString());
				}else if(1 == count) {
     
					//电话
					customerPhoneInfoDo.setPhone(str==null?"":str.toString());
				}else if(2 == count) {
     
					//区域
					customerPhoneInfoDo.setRegion(str==null?"":str.toString());
				}else if(3 == count) {
     
					//客户需求
					customerPhoneInfoDo.setCustomerNeed(str==null?"":str.toString());
				}else if(4 == count) {
     
					//宣传人
					customerPhoneInfoDo.setPublicist(str==null?"":str.toString());
				}else if(5 == count) {
     
					//带队人
					customerPhoneInfoDo.setLeader(str==null?"":str.toString());
				}else if(6 == count) {
     
					//经理
					customerPhoneInfoDo.setManager(str==null?"":str.toString());
				}
				customerPhoneInfoDo.setSign(sign);
				count ++;
			}
			doList.add(customerPhoneInfoDo);
		}
		//封装好实体集合后,逐个再保存数据
		boolean insertCustomerInfo = false;
		if(doList.size() > 0) {
     
			for(CustomerPhoneInfoDo customerPhoneInfoDo : doList) {
     
				insertCustomerInfo = customerInfoMapper.insertCustomerInfo(customerPhoneInfoDo);
			}
		}
		return insertCustomerInfo;
	}
	
	@Override
	public Workbook excelEmportFile(List<ArrayList<String>> readExcel, String fileName, String postfix) {
     
		// 读取数据封装实体
		if(readExcel.size() == 0) {
     
			return null;
		}
		List<CustomerPhoneInfoDo> custorList = getCustorList(readExcel);
		List<CustomerPhoneInfoDo> newDoList = new ArrayList<>();
		for(CustomerPhoneInfoDo customerPhoneInfoDo : custorList) {
     
			if(newDoList.size() > 0) {
     
				boolean status = true;
				//判断该条数据在新的集合中是否存在
				for(CustomerPhoneInfoDo cusDo : newDoList) {
     
					if(customerPhoneInfoDo.getPhone() != null) {
     
						if(cusDo.getPhone() != null) {
     
							if(customerPhoneInfoDo.getPhone().equals(cusDo.getPhone())) {
     
								status = false;
							}
						}
					}
				}
				// 判断该条数据是否存在新的对象中,true则不存在
				if(status) {
     
					newDoList.add(customerPhoneInfoDo);
				}
			} else {
     
				newDoList.add(customerPhoneInfoDo);
			}
		}
		//**根据文件的后缀名选择执行方法整理excel文件**
	    if(!ExcelUtil.EMPTY.equals(postfix)){
     
	        if(ExcelUtil.OFFICE_EXCEL_2003_POSTFIX.equals(postfix)){
     
	        	return exportXLSExcel(newDoList, fileName);
	        }else if(ExcelUtil.OFFICE_EXCEL_2010_POSTFIX.equals(postfix)){
     
	        	return exportXLSXExcel(newDoList, fileName);
	        }
	    }
		return null;
	}
	
	/*
	 * 将读取的excel文件内容封装
	 */
	public List<CustomerPhoneInfoDo> getCustorList(List<ArrayList<String>> readExcel){
     
		List<CustomerPhoneInfoDo> doList = new ArrayList<>();
		for(List<String> sList : readExcel) {
     
			CustomerPhoneInfoDo customerPhoneInfoDo = new CustomerPhoneInfoDo();
			int count = 0;
			for(String str : sList) {
     
				if(0 == count) {
     
					// 客户名称
					customerPhoneInfoDo.setUserName(str==null?"":str.toString());
				}else if(1 == count) {
     
					//电话
					customerPhoneInfoDo.setPhone(str==null?"":str.toString());
				}else if(2 == count) {
     
					//区域
					customerPhoneInfoDo.setRegion(str==null?"":str.toString());
				}else if(3 == count) {
     
					//客户需求
					customerPhoneInfoDo.setCustomerNeed(str==null?"":str.toString());
				}else if(4 == count) {
     
					//宣传人
					customerPhoneInfoDo.setPublicist(str==null?"":str.toString());
				}else if(5 == count) {
     
					//带队人
					customerPhoneInfoDo.setLeader(str==null?"":str.toString());
				}else if(6 == count) {
     
					//经理
					customerPhoneInfoDo.setManager(str==null?"":str.toString());
				}
				count ++;
			}
			doList.add(customerPhoneInfoDo);
		}
		return doList;
	}
	
	public Workbook exportXLSXExcel(List<CustomerPhoneInfoDo> doList,String fileName) {
     
		// 创建Excel表。 
        Workbook book = new XSSFWorkbook();
        // 在当前Excel创建一个子表  
        Sheet sheet = book.createSheet("DIS"+fileName);
        // 设置表头信息(写入Excel左上角是从(0,0)开始的) 
        Row row = sheet.createRow(0);
        row.createCell(0).setCellValue("客户姓名");
        row.createCell(1).setCellValue("电话");
        row.createCell(2).setCellValue("区域");
        row.createCell(3).setCellValue("客户需求");
        row.createCell(4).setCellValue("宣传人");
        row.createCell(5).setCellValue("带队人");
        row.createCell(6).setCellValue("经理");
    	int count = 1;
    	for(CustomerPhoneInfoDo CustomerPhoneInfoDo : doList) {
     
    		// 行  
            Row rows = sheet.createRow(count);
            // 单元格
            // 写入数据 
            rows.createCell(0).setCellValue(CustomerPhoneInfoDo.getUserName());
            rows.createCell(1).setCellValue(CustomerPhoneInfoDo.getPhone());
            rows.createCell(2).setCellValue(CustomerPhoneInfoDo.getRegion());
            rows.createCell(3).setCellValue(CustomerPhoneInfoDo.getCustomerNeed());
            rows.createCell(4).setCellValue(CustomerPhoneInfoDo.getPublicist());
            rows.createCell(5).setCellValue(CustomerPhoneInfoDo.getLeader());
            rows.createCell(6).setCellValue(CustomerPhoneInfoDo.getManager());
            count ++;
    	}
        // 保存excel文件 
        /*try {
			book.write(new FileOutputStream("D://Excel//" + "DIS"+fileName + ".xlsx"));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}*/
    	return book;
	}
	
	public Workbook exportXLSExcel(List<CustomerPhoneInfoDo> doList,String fileName) {
     
		// 创建Excel表。 
        Workbook book = new HSSFWorkbook();
        // 在当前Excel创建一个子表  
        Sheet sheet = book.createSheet("DIS"+fileName);
        // 设置表头信息(写入Excel左上角是从(0,0)开始的) 
        Row row = sheet.createRow(0);
        row.createCell(0).setCellValue("客户姓名");
        row.createCell(1).setCellValue("电话");
        row.createCell(2).setCellValue("区域");
        row.createCell(3).setCellValue("客户需求");
        row.createCell(4).setCellValue("宣传人");
        row.createCell(5).setCellValue("带队人");
        row.createCell(6).setCellValue("经理");
    	int count = 1;
    	for(CustomerPhoneInfoDo CustomerPhoneInfoDo : doList) {
     
    		// 行  
            Row rows = sheet.createRow(count);
            // 单元格
            // 写入数据 
            rows.createCell(0).setCellValue(CustomerPhoneInfoDo.getUserName());
            rows.createCell(1).setCellValue(CustomerPhoneInfoDo.getPhone());
            rows.createCell(2).setCellValue(CustomerPhoneInfoDo.getRegion());
            rows.createCell(3).setCellValue(CustomerPhoneInfoDo.getCustomerNeed());
            rows.createCell(4).setCellValue(CustomerPhoneInfoDo.getPublicist());
            rows.createCell(5).setCellValue(CustomerPhoneInfoDo.getLeader());
            rows.createCell(6).setCellValue(CustomerPhoneInfoDo.getManager());
            count ++;
    	}
        // 保存excel文件 
        /*try {
			book.write(new FileOutputStream("D://Excel//" + "DIS"+fileName + ".xls"));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} */
    	return book;
	}
}

内容较多也较详细,希望对大家有所帮助,如有高手经过,请给出指点意见。

你可能感兴趣的:(后端,Excel导入导出,POI,Java)