利用poi可以實現excel文件導入和導出功能 本例子結合了springboot做demo
pom文件
<properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>1.5.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-freemarker --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> <version>1.5.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.16</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.16</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>3.16</version> </dependency> </dependencies>
一個demo的controller類
@RestController public class DemoController { private final Logger LOGGER = LoggerFactory.getLogger(DemoController.class); @RequestMapping("upload") public Object upload(@PathVariable("file") MultipartFile file) throws Exception { if (file == null || file.getInputStream() == null) { LOGGER.error("文件上傳失敗"); return "文件上傳失敗"; } if (file.getSize() > 5 * 1024 * 1024) { LOGGER.error("文件太大,上傳失敗"); return "文件太大,上傳失敗"; } FileTypeUtil.FileType fileType = FileTypeUtil.getFileType(file.getInputStream()); //XLS_DOC --》2007之前的excel類型 XLSX_DOCX--》 2007之後的excel類型 if (fileType == FileTypeUtil.FileType.XLS_DOC) { LOGGER.info("開始解析XLS_DOC文件"); HSSFWorkbook hssfWorkbook = new HSSFWorkbook(file.getInputStream()); List<User> getData = readOldExcel(hssfWorkbook); if (getData == null) { LOGGER.error("解析失敗..."); return "文件數據解析失敗"; } LOGGER.info("數據解析成功"); file.getInputStream().close(); return getData; } else if (fileType == FileTypeUtil.FileType.XLSX_DOCX) { LOGGER.info("開始解析XLSX_DOCX文件"); XSSFWorkbook xssfWorkbook = new XSSFWorkbook(file.getInputStream()); List<User> getData = readExcel(xssfWorkbook); if (getData == null) { LOGGER.error("解析失敗..."); return "文件數據解析失敗"; } LOGGER.info("數據解析成功"); file.getInputStream().close(); return getData; } else { LOGGER.error("上傳文件類型不正確"); return "文件類型不正確"; } } @RequestMapping("download") public void download(HttpServletResponse response) throws Exception { //獲取模板的輸入流 InputStream inputStream = UploadController.class.getClassLoader().getResourceAsStream("templates" + File.separator + "xx.xlsx"); if (inputStream == null) { LOGGER.error("模板文件的路徑不正確"); } //測試數據 List<User> users = new ArrayList<User>(); for (int i = 0; i < 10; i++) { User user = new User(); user.setId(i + 1); user.setUsername("張三" + i + 1); user.setPassword("123" + i + 1); users.add(user); } //獲取模板的工作薄 XSSFWorkbook workbook = new XSSFWorkbook(inputStream); XSSFSheet sheetAt = workbook.getSheetAt(0); XSSFRow row = sheetAt.getRow(0); short rowHeight = row.getHeight(); XSSFRow row1 = null; XSSFCell cell = null; for (int j = 0; j < users.size(); j++) { User user = users.get(j); row1 = sheetAt.createRow(j + 1); row1.setHeight(rowHeight); cell = row1.createCell(0); cell.setCellValue(user.getId()); cell = row1.createCell(1); cell.setCellValue(user.getUsername()); cell = row1.createCell(2); cell.setCellValue(user.getPassword()); } String filename = new String("文件".getBytes("UTF-8"),"ISO8859-1"); LOGGER.info("文件名"+filename); response.setContentType("application/vnd.ms-excel;charset=utf-8"); response.setHeader("Content-disposition", "attachment;filename="+filename+".xlsx"); workbook.write(response.getOutputStream()); LOGGER.info("文件下載成功!!"); response.getOutputStream().flush(); response.getOutputStream().close(); workbook.close(); } //處理2007之前的excel private List<User> readOldExcel(HSSFWorkbook hssfWorkbook) { List<User> users = new ArrayList<User>(); HSSFSheet sheetAt = hssfWorkbook.getSheetAt(0); HSSFCell cell = null; HSSFRow row = null; for (int i = sheetAt.getFirstRowNum(); i < sheetAt.getPhysicalNumberOfRows(); i++) { row = sheetAt.getRow(i); if (row == null) { LOGGER.warn("獲取到一個空行-------》》》》》》" + i + "行"); continue; } Object[] objects = new Object[row.getLastCellNum()]; for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) { cell = row.getCell(j); switch (cell.getCellTypeEnum()) { case STRING: objects[j] = cell.getStringCellValue(); System.out.println(cell.getStringCellValue()); break; case _NONE: objects[j] = ""; break; case BOOLEAN: objects[j] = cell.getBooleanCellValue(); System.out.println(cell.getBooleanCellValue()); break; case NUMERIC: //處理double類型的 1.0===》1 DecimalFormat df = new DecimalFormat("0"); String s = df.format(cell.getNumericCellValue()); objects[j] = s; System.out.println(s); break; default: objects[j] = cell.toString(); } } //處理數據 if (objects != null) { User user = new User(); user.setId(Integer.parseInt(objects[0].toString())); user.setUsername((String) objects[1]); user.setPassword(objects[2].toString()); users.add(user); } } return users; } //處理2007之後的excel private List<User> readExcel(XSSFWorkbook xssfWorkbook) { List<User> users = new ArrayList<User>(); //獲得excel第一個工作薄 XSSFSheet sheet = xssfWorkbook.getSheetAt(0); //行 XSSFRow row = null; //列 XSSFCell cell = null; for (int i = sheet.getFirstRowNum(); i < sheet.getPhysicalNumberOfRows(); i++) { //獲取每一行 row = sheet.getRow(i); //判斷是否出現空行 if (row == null) { LOGGER.warn("獲取到一個空行-------》》》》》》" + i + "行"); continue; } Object[] objects = new Object[row.getLastCellNum()]; for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) { cell = row.getCell(j); if (cell == null) { LOGGER.warn("獲取到一個空列------------》》》》》》" + j + "列"); continue; } //第一行數據 switch (cell.getCellTypeEnum()) { case STRING: objects[j] = cell.getStringCellValue(); System.out.println(cell.getStringCellValue()); break; case _NONE: objects[j] = ""; break; case BOOLEAN: objects[j] = cell.getBooleanCellValue(); System.out.println(cell.getBooleanCellValue()); break; case NUMERIC: //處理double類型的 1.0===》1 DecimalFormat df = new DecimalFormat("0"); String s = df.format(cell.getNumericCellValue()); objects[j] = s; System.out.println(s); break; default: objects[j] = cell.toString(); } } //處理數據 if (objects != null) { User user = new User(); user.setId(Integer.parseInt(objects[0].toString())); user.setUsername((String) objects[1]); user.setPassword(objects[2].toString()); users.add(user); } } return users; } //處理excel中的圖片 2007之後 ---》獲取 String裏面保存着 這個圖片的座標 private Map<String, PictureData> getExcelPic(XSSFWorkbook xssfWorkbook, XSSFSheet xssfSheet) { Map<String, PictureData> map = new HashMap<String, PictureData>(); for (POIXMLDocumentPart poixmlDocument : xssfWorkbook.getRelations()) { if (poixmlDocument instanceof XSSFDrawing) { //拿到 drawing XSSFDrawing xssfDrawing = (XSSFDrawing) poixmlDocument; //拿到所有的圖形 List<XSSFShape> shapes = xssfDrawing.getShapes(); for (XSSFShape xssfShape : shapes) { if (xssfShape instanceof XSSFPicture) { //拿到picture XSSFPicture xssfPicture = (XSSFPicture) xssfShape; //拿到anchor 這裏存在 圖片的座標 XSSFClientAnchor size = xssfPicture.getPreferredSize(); int row1 = size.getRow1(); short col1 = size.getCol1(); //自定義一個座標 String xy = String.valueOf(row1) + "_" + String.valueOf(col1); map.put(xy, (PictureData) xssfPicture.getPictureData()); } } } } return map; } //處理excel中的圖片 2007之前 private Map<String, PictureData> getOldExcelPic(HSSFWorkbook hssfWorkbook, HSSFSheet hssfSheet) { Map<String, PictureData> map = new HashMap<String, PictureData>(); //需要先獲取 所有的圖片 通過 workbook List<HSSFPictureData> pictures = hssfWorkbook.getAllPictures(); if (pictures.size() > 0) { //通過sheet 獲得sheet裏面所有的 shape List<HSSFShape> children = hssfSheet.getDrawingPatriarch().getChildren(); for (HSSFShape hssfShape : children) { //通過shape 獲得anchor 來獲取圖片座標 HSSFAnchor anchor = hssfShape.getAnchor(); if (hssfShape instanceof HSSFPicture) { //獲得picture HSSFPicture hssfPicture = (HSSFPicture) hssfShape; //2007之前的需要通過 picture的索引 ----》 在全局的圖片信息裏面獲取圖片數據 int i = hssfPicture.getPictureIndex() - 1; //獲得圖片數據 HSSFPictureData hssfPictureData = pictures.get(i); //拿到圖片的座標 String xy = anchor.getDx1() + "_" + anchor.getDy1(); map.put(xy, (PictureData) hssfPictureData); } } return map; } else { return null; } } }