springboot中Excel文件导入导出

Java学习大纲(持续更新):https://blog.csdn.net/weixin_39778570/article/details/94667501
更多IT学习资源:https://blog.csdn.net/weixin_39778570/article/details/100052454

Excel文件导入

从前端传递excel文件到后端,通过ajax
这里使用的是lay-ui的控件

upload.render({ 
            elem: '#test' //绑定元素
            ,accept: 'file'
            ,url: '/xxx/xxx/upload' //上传接口
            ,before: function(obj) { 
                layer.msg('文件上传中...', { 
                    icon: 16,
                    shade: 0.01,
                    time: 0
                })
            },
            done: function(res) { 
                layer.close(layer.msg(res.msg));//关闭上传提示窗口
            }
        });

后端Controller获取数据并处理

@RequestMapping("upload")
	@ResponseBody
	public BaseResponse doUpload(HttpServletRequest request) throws IOException { 
		MultipartHttpServletRequest mreq = null;
		if(request instanceof  MultipartHttpServletRequest){ 
			mreq = (MultipartHttpServletRequest) request;
		}else { 
			return BaseResponse.fail ();
		}
		try{ 
			boolean flag = xxx.analysisFile(mreq);
			if(!flag){ 
				return BaseResponse.fail ();
			}
			return BaseResponse.success();
		}catch (Exception e){ 
			return BaseResponse.fail ();
		}
	}

Server层xxx.analysisFile(mreq)

public boolean analysisFile(MultipartHttpServletRequest mreq){ 
		List<Map> maps = null;
		try { 
			maps = ExcelUtils.analysisFile (mreq);
		} catch (Exception e) { 
			return false;
		}
		if(maps==null){ 
			return false;
		}else{ 
			// 处理信息
			return true;
		}
	}

解析Excel文件请求的工具类(可以直接复用)

import org.apache.poi.ss.usermodel.*;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.List;

/** * Excel处理工具 */
public class ExcelUtils { 

    /** * 处理HTTP请求里是file文件 * @param mreq * @return 返回List<Map>每个Map存放一行 */
    public static List<Map> analysisFile(MultipartHttpServletRequest mreq)throws Exception{ 
        InputStream inputStream= null;
        try { 
            inputStream = mreq.getFile ("file").getInputStream ();
        } catch (IOException e) { 
            throw e;
        }
        String fileName = mreq.getFile ("file").getOriginalFilename ();
        Workbook workbook = null;
        try { 
            //判断什么类型文件
            if (fileName.endsWith(".xls") || fileName.endsWith(".xlsx")) { 
                workbook = WorkbookFactory.create(inputStream);
            }
        } catch (Exception e) { 
            throw e;
        }
        if (workbook == null) { 
            return null;
        } else { 
            //获取所有的工作表的的数量
            int numOfSheet = workbook.getNumberOfSheets ();
            System.out.println (numOfSheet + "--->numOfSheet");
            List<Map> mapList = new ArrayList<> ();
            //遍历表
            for (int i = 0; i < numOfSheet; i++) { 
                //获取一个sheet也就是一个工作本。
                Sheet sheet = workbook.getSheetAt (i);
                if (sheet == null) { 
                    continue;
                }
                //获取一个sheet有多少Row
                int lastRowNum = sheet.getLastRowNum ();
                if (lastRowNum == 0) { 
                    continue;
                }
                Row row;
                // 行头
                List<String> headName = new ArrayList<>();
                if(lastRowNum>0){ 
                    row = sheet.getRow (0);
                    // 获取一个Row有多少Cell
                    short lastCellNum = row.getLastCellNum ();
                    for (int k = 0; k <= lastCellNum; k++) { 
                        if (row.getCell (k) == null) { 
                            continue;
                        }
                        String res = getCellVal(row.getCell (k));
                        headName.add (res);
                    }
                }

                // 每一行的内容
                for (int j = 1; j <= lastRowNum; j++) { 
                    row = sheet.getRow (j);
                    if (row == null) { 
                        continue;
                    }
                    //获取一个Row有多少Cell
                    short lastCellNum = row.getLastCellNum ();
                    Map<String,String> rowMap = new HashMap ();
                    for (int k = 0; k <= lastCellNum; k++) { 
                        if (row.getCell (k) == null) { 
                            continue;
                        }
                        String res = getCellVal(row.getCell (k));
                        rowMap.put (headName.get (k), res);
                    }
                    mapList.add (rowMap);
                }
            }
            return mapList;
        }
    }

    private static String getCellVal(Cell cell) { 
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd"); //日期格式yyyy-mm-dd
        DecimalFormat df = new DecimalFormat("0");
        String val;
        switch (cell.getCellType()) { 
            case Cell.CELL_TYPE_NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) { 
                    val = fmt.format(cell.getDateCellValue()); //日期型
                } else { 
                    val = df.format(cell.getNumericCellValue()); //数字型
                }
                break;
            case Cell.CELL_TYPE_STRING: //文本类型
                val = cell.getStringCellValue();
                break;
            case Cell.CELL_TYPE_BOOLEAN: //布尔型
                val = String.valueOf(cell.getBooleanCellValue());
                break;
            case Cell.CELL_TYPE_BLANK: //空白
                val = cell.getStringCellValue();
                break;
            case Cell.CELL_TYPE_ERROR: //错误
                val = "错误";
                break;
            case Cell.CELL_TYPE_FORMULA: //公式
                try { 
                    val = String.valueOf(cell.getStringCellValue());
                } catch (IllegalStateException e) { 
                    val = String.valueOf(cell.getNumericCellValue());
                }
                break;
            default:
                val = cell.getRichStringCellValue() == null ? null : cell.getRichStringCellValue().toString();
        }
        return val;
    }
}

Excel 文件导出

由于ajax 是无法直接导出excel的,因为ajax返回值只能是字符流,而导出excel是后台往浏览器中写入二进制的字节流
流程是这样的,前端发送一个ajax请求到后端,后端缓存请求数据,并保存请求,返回给浏览器一个UUID,浏览器通过UUID再发起请求(可以通过window.location.href的方式),服务器把excel文件写入response中显示到浏览器

前端请求

form.on('submit(export)', function(data){ 
            var field = data.field;
            $.ajax({ 
                url:'<@spring.url "/xxx/ttt/export"/>',
                dataType : "json",
                data : JSON.stringify(field),
                contentType : "application/json; charset=utf-8",
                type : "POST",
                async: true,
                success : function(data){ 
                    var key =data.msg
                    window.location.href = "/xxx/ttt/doExport?key="+key
                }
            })
        });

后端处理请求,先缓存,再查询(为了简单起见这里就不查询了),再清楚缓存

/** * 由于ajax无法直接导出excel,所以第一次把请求生成的ExcelParam缓存起来,然后前端再次window.open(url); */
    public static Map<String, Xxx> excelParamCache = new ConcurrentHashMap<> ();

    //第一步缓存参数
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/export")
    @ResponseBody
    public BaseResponse export(@RequestBody Xxx requestVo) { 
        String key = UUID.randomUUID().toString();
        excelParamCache.put(key,requestVo);
        return new BaseResponse(0,key);
    }

    @RequestMapping(value = "doExport")
    public BaseResponse doExport(String key, HttpServletRequest request, HttpServletResponse response) throws IOException { 
        if(key==null){ 
            return BaseResponse.fail ();
        }
        try { 
            if(!excelParamCache.containsKey (key)){ 
                return BaseResponse.fail ();
            }
            HSSFWorkbook workbook = new HSSFWorkbook ();
            HSSFSheet sheet = workbook.createSheet ("信息表");

            // 设置要导出的文件的名字
            String fileName = "报表-" + new Date () + ".xls";

            // 新增数据行,并且设置单元格数据
            int rowNum = 1;

            // headers表示excel表中第一行的表头 在excel表中添加表头
            String[] headers = { "id", "uid", "地址", "城市"};
            HSSFRow row = sheet.createRow (0);
            for (int i = 0; i < headers.length; i++) { 
                HSSFCell cell = row.createCell (i);
                HSSFRichTextString text = new HSSFRichTextString (headers[i]);
                cell.setCellValue (text);
            }

            //在表中存放查询到的数据放入对应的列
            for (int i = 0; i < 4; i++) { 
                HSSFRow row1 = sheet.createRow (rowNum);
                row1.createCell (0).setCellValue (1);
                row1.createCell (1).setCellValue (2);
                row1.createCell (2).setCellValue (3);
                row1.createCell (3).setCellValue ("hhh");
                rowNum++;

            }

            response.setContentType ("application/octet-stream");
            response.setHeader ("Content-disposition", "attachment;filename=" + fileName);
            response.flushBuffer ();
            workbook.write (response.getOutputStream ());
        }catch (Exception e){ 
            excelParamCache.remove(key);
        }finally { 
            excelParamCache.remove(key);
        }
        return BaseResponse.success ();
    }

依赖

<!-- 文件上传 -->
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>3.14</version>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>3.14</version>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml-schemas</artifactId>
      <version>3.14</version>
    </dependency>

执行结果
《springboot中Excel文件导入导出》

    原文作者:向前走别回头
    原文地址: https://blog.csdn.net/weixin_39778570/article/details/102941456
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞