我所知道報表之POI讀取加載Excel、報表導入、報表導出

前兩篇文章都是建立Excel文檔,那麼如何將Excel文檔讀取出來進行操做呢?程序員

1、加載解析Excel文檔


好比說當前有一個Excel文檔裏,如何將這些內容讀取出來呢?數據庫

image.png

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-

2、需求報表導入


實現批量導入員工功能

頁面端上傳excel表格,服務端解析表格獲取數據,批量新增用戶

image.png

咱們在使用導入的時候,要根據提供的模板填寫相應的數據信息

好比說咱們當前有一個模板,裏面的信息是

image.png

那麼咱們如何將這些信息讀取到,而且將它們保存到服務器數據庫中?

第一步:搭建環境、引入JAR包或者MAVEN座標

<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>

第二步:根據解析Excel文檔思路獲取上傳文件

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;
}
  1. 根據思路咱們建立對應的用戶類,以及測試
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();//部門編碼
}

這樣咱們就不會出現轉換的問題了

3、需求文檔導出


完成當月人事報表的導出:包含當月入職員工信息,離職員工信息

主要思路分爲:獲取報表數據、建立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刷臉登陸實戰開發(報表相關視頻)

相關文章
相關標籤/搜索