前兩篇文章都是建立Excel文檔,那麼如何將Excel文檔讀取出來進行操做呢?程序員
好比說當前有一個Excel文檔裏,如何將這些內容讀取出來呢?數據庫
1.咱們須要獲取到這個Excel文檔apache
2.獲取須要操做的sheet表,從0下標開始表明爲第一頁服務器
3.獲取sheet表裏的每一行、從0下標開始表明爲第一行app
4.獲取sheet表裏的每一列、從0下標開始表明爲第一列測試
//單元格樣式 public static void main(String[] args) throws Exception { //1.建立workbook工做簿 Workbook wb = new XSSFWorkbook("E:\\demo.xlsx"); //2.獲取sheet 從0開始 Sheet sheet = wb.getSheetAt(0); //循環全部行getLastRowNum指的是sheet表裏的最後一行 for (int rowNum = 0; rowNum <sheet.getLastRowNum(); rowNum++) { Row row = sheet.getRow(rowNum);//獲取行對象 //循環每行中的全部單元格 for(int cellNum = 0; cellNum < row.getLastCellNum();cellNum++) { Cell cell = row.getCell(cellNum);//獲取單元格列對象 } } }
如圖發現,其實單元格第一列、第二列是沒有內容的,其實能夠從第三列開始ui
那麼咱們在操做excel單元格的時候呢,會有不一樣的屬性類型的this
咱們讀取的時候,要根據當前單元格的屬性,賦值不一樣的數據類型編碼
//獲取數據 private static Object getValue(Cell cell) { Object value = null; switch (cell.getCellType()) { case STRING: //字符串類型 value = cell.getStringCellValue(); break; case BOOLEAN: //boolean類型 value = cell.getBooleanCellValue(); break; case NUMERIC: //數字類型(包含日期和普通數字) if(DateUtil.isCellDateFormatted(cell)) { value = cell.getDateCellValue(); }else{ value = cell.getNumericCellValue(); } break; case FORMULA: //公式類型 value = cell.getCellFormula(); break; default: break; } return value; }
咱們能夠打印輸出校驗獲取的數據是否與Excel文檔裏的一致spa
//單元格樣式 public static void main(String[] args) throws Exception { //1.建立workbook工做簿 Workbook wb = new XSSFWorkbook("E:\\demo.xlsx"); //2.獲取sheet 從0開始 Sheet sheet = wb.getSheetAt(0); //3.建立行對象、列對象 避免重複浪費 Row row = null; Cell cell = null; //循環全部行getLastRowNum指的是sheet表裏的最後一行 for (int rowNum = 0; rowNum <sheet.getLastRowNum(); rowNum++) { Row row = sheet.getRow(rowNum);//獲取行對象 StringBuilder sb = new StringBuilder(); //循環每行中的全部單元格 for(int cellNum = 2; cellNum < row.getLastCellNum();cellNum++) { Cell cell = row.getCell(cellNum);//獲取單元格列對象 } System.out.println(sb.toString()); } } 運行結果以下: 序號-姓名-年齡-家庭住址-出生日期 1-張三-18-北京-北京-Thu Nov 01 00:00:00 CST 2001- 2-李四-20-上海-北京-Thu Nov 01 00:00:00 CST 2001- 3-王五-18-廣州-北京-Thu Nov 01 00:00:00 CST 2001- 4-趙六-20-深圳-北京-Thu Nov 01 00:00:00 CST 2001-
實現批量導入員工功能
頁面端上傳excel表格,服務端解析表格獲取數據,批量新增用戶
咱們在使用導入的時候,要根據提供的模板填寫相應的數據信息
好比說咱們當前有一個模板,裏面的信息是
那麼咱們如何將這些信息讀取到,而且將它們保存到服務器數據庫中?
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>4.0.1</version> </dependency>
1.咱們須要獲取到這個Excel文檔
2.獲取須要操做的sheet表,從0下標開始表明爲第一頁
3.獲取sheet表裏的每一行、從0下標開始表明爲第一行
4.獲取sheet表裏的每一列、從0下標開始表明爲第一列
5.同時咱們讀取的時候,要根據當前單元格的屬性,賦值不一樣的數據類型
//獲取數據 private static Object getValue(Cell cell) { Object value = null; switch (cell.getCellType()) { case STRING: //字符串類型 value = cell.getStringCellValue(); break; case BOOLEAN: //boolean類型 value = cell.getBooleanCellValue(); break; case NUMERIC: //數字類型(包含日期和普通數字) if(DateUtil.isCellDateFormatted(cell)) { value = cell.getDateCellValue(); }else{ value = cell.getNumericCellValue(); } break; case FORMULA: //公式類型 value = cell.getCellFormula(); break; default: break; } return value; }
class User{ private String name; private String tel; private String code; private String deptCode; public User(Object[] obj) { this.name = obj[0].toString();//用戶名 this.tel = obj[1].toString();//手機號 this.code = obj[2].toString();//工號 this.deptCode = obj[5].toString();//部門編碼 } //省略get、set方法 }
@RequestMapping(value="/user/import", method = RequestMethod.POST) public Result importExcel(@RequestParam(name = "file") MultipartFile attachment)throws Exception { //1.根據上傳流信息建立工做簿 Workbook workbook = WorkbookFactory.create(attachment.getInputStream()); //2.獲取第一個sheet Sheet sheet = workbook.getSheetAt(0); List<User> users = new ArrayList<>(); //3.從第二行開始獲取數據 for (int rowNum = 1; rowNum <sheet.getLastRowNum(); rowNum++) { //獲取行對象 Row row = sheet.getRow(rowNum); //獲取該行的全部列單元格數量 Object objs[] = new Object[row.getLastCellNum()]; //從第二列獲取數據 for(int cellNum = 0; cellNum < row.getLastCellNum();cellNum++) { Cell cell = row.getCell(cellNum); objs[cellNum] = getValue(cell); } //根據每一列構造用戶對象 User user = new User(objs); users.add(user); } //第一個參數:用戶列表,第二個參數:部門編碼 userService.save(users); return Result.SUCCESS(); }
@Transactional public void save(List<User> users) throws Exception { for (User user : users) { userDao.save(user); } }
若對於Excel文檔中,數字有時會攜帶.0小數點,手機號會存在科學記數法問題
這樣的狀況咱們要怎麼轉化處理呢?
public User(Object[] obj) { this.name = obj[0].toString();//用戶名 this.tel = new DecimalFormat("#").format(obj[1].toString());//手機號 this.code = new DecimalFormat("#").format(obj[2].toString());//工號 this.deptCode = obj[5].toString();//部門編碼 }
這樣咱們就不會出現轉換的問題了
完成當月人事報表的導出:包含當月入職員工信息,離職員工信息
主要思路分爲:獲取報表數據、建立excel、輸出下載
@RequestMapping(value = "/export/{month}", method = RequestMethod.GET) public void export(@PathVariable(name = "month") String month) throws Exception { //1.構造數據 List<User> list = userService.findByReport(companyId,month+"%"); //2.建立工做簿 XSSFWorkbook workbook = new XSSFWorkbook(); //3.構造sheet String[] titles = {"編號", "姓名", "手機"}; Sheet sheet = workbook.createSheet(); Row row = sheet.createRow(0); int titleInext = 0; //4.寫入標題 for (String title : titles) { Cell cell = row.createCell(titleInext++); cell.setCellValue(title); } Cell cell = null; //5.寫入單元格 for (user report : list) { Row dataRow = sheet.createRow(titleInext++); //編號 cell = dataRow.createCell(0); cell.setCellValue(report.getUserId()); //姓名 cell = dataRow.createCell(1); cell.setCellValue(report.getUsername()); //手機 cell = dataRow.createCell(2); cell.setCellValue(report.getMobile()); } //6.輸出文件下載 String fileName = URLEncoder.encode(month+"人員信息.xlsx", "UTF-8"); response.setContentType("application/octet-stream"); response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes("ISO8859-1"))); response.setHeader("filename", fileName); workbook.write(response.getOutputStream()); }
黑馬程序員:基於SaaS平臺的iHRM刷臉登陸實戰開發(報表相關視頻)