1. 程式人生 > >POI——動態修改Excel模板下拉框

POI——動態修改Excel模板下拉框

需求:

在匯入頁面放置了的Excel模板,最開始內容是寫死的。現在需要將資料庫的資料動態的載入到excel模板的下拉框中。使用的為poi.xssf

相關jar包

poi-3.10-FINAL-20140208.jar
poi-ooxml-3.10-FINAL-20140208.jar
poi-ooxml-schemas-3.10-FINAL-20140208.jar

方法思路:

讀取Excel模板檔案——從資料庫讀取下拉框所需資料——將讀取出的資料先寫入另一張sheet(資料來源sheet)——為展示資料的sheet設定資料驗證規則,增加資料驗證——將更新後的workbook儲存到新的path

該方法返回path到controller,之後經過檔案流處理即可實現模板的下載

   	/**
   	 * update poi select 
   	 * @param realPath
   	 * @author cloudHeart
   	 * @throws FileNotFoundException 
   	 */
	public String setPOISelect(String realPath) throws FileNotFoundException {
		InputStream is = null;
		XSSFWorkbook wb = null;
		
		//讀取檔案 
	     try {
			is = new FileInputStream(new File(realPath));
			wb = new XSSFWorkbook(is);
			XSSFSheet sheet = wb.getSheetAt(0);
			int rows = sheet.getLastRowNum() + 1; //行數
			System.out.println("rows = " + rows);
			
			//設定部門下拉框
			ArrayList<String> orgNameList = new ArrayList<>(30);
			List<Org> orgList = dao.findAll();
			for (Org one : orgList) {
				String name = one.getOrgName();
				orgNameList.add(name);
			}
			String[] orgArray = orgNameList.toArray(new String[orgNameList.size()]); 
			wb = selectUpda're(wb, sheet, orgArray, 2, 9, 1, 1, 2, 'B');
			
			//由於POI開啟讀取檔案後再儲存時bug問題, 只能重新定義一個新的Excel寫入資料  
			String subPath = realPath.substring(0, realPath.lastIndexOf("\\"));
			String path = subPath.concat("\\模板");
			createExcel(wb, path);
			return path;
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return realPath; 
	    
		
	}

因為可能更新多個不同型別下拉框資料,所以設定了selectNum和selectAlpha

	/**
     * @param wb XSSFWorkbook物件
     * @param realSheet 需要操作的sheet物件
     * @param datas 下拉的列表資料
     * @param startRow 開始行
     * @param endRow 結束行
     * @param startCol 開始列
     * @param endCol 結束列
     * @param selectMum 資料來源sheet的下拉資料來源對應列
     * @param selectAlpha 資料來源sheet的下拉資料對應字母
     * @return
     * @throws Exception
     */
    public XSSFWorkbook dropDownList2003(XSSFWorkbook wb, XSSFSheet realSheet, String[] datas, int startRow, int endRow,
                                                int startCol, int endCol, int selectNum ,char seletAlpha)
                                                                                                                       throws Exception {
    	String hiddenSheetName = "字典項";
       // XSSFWorkbook workbook = (XSSFWorkbook) wb;
        // 資料來源sheet 原模板已有專門的資料來源sheet,沒有的話用 wb.createSheet("名稱")建立一個即可
        XSSFSheet hidden = (XSSFSheet) wb.getSheetAt(1);
        // 資料來源sheet頁不顯示
        wb.setSheetHidden(1, true);
        // 將下拉列表的資料放在資料來源sheet上
        XSSFRow row = null;
        XSSFCell cell = null;
        for (int i = 0, length = datas.length; i < length; i++) {
            //row = hidden.createRow(i);
            row = hidden.getRow(i);
            if(row == null || ("").equals(row)){
            	row = hidden.createRow(i);
            }
           cell = row.getCell(selectNum-1);
           if(cell == null || ("").equals(cell)){
        	   cell = row.createCell(selectNum -1);
           }
           cell.setCellValue(datas[i]);
        }   
        	//建立規則
        XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(realSheet);
        XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint) dvHelper
        		.createFormulaListConstraint(hiddenSheetName + "!$"+seletAlpha+"$1:$"+seletAlpha+"" + datas.length);
        //DataValidationConstraint  constraint = DVConstraint.createFormulaListConstraint(hiddenSheetName + "!$"+seletAlpha+"$1:$"+seletAlpha+"" + datas.length);
        CellRangeAddressList addressList = null; // 設定在哪個單元格生效  
        DataValidation validation = null; // 建立規則物件  
        row = null;
        cell = null;
        // 迴圈指定單元格下拉資料
        for (int i = startRow; i <= endRow; i++) {
            row = (XSSFRow) realSheet.getRow(i);
            cell = row.getCell(startCol); 
            addressList = new CellRangeAddressList(i, i, startCol, endCol);
            validation = dvHelper.createValidation(dvConstraint, addressList);
            //validation = new HSSFDataValidation(addressList, constraint);
            //HSSF和XSSF的建立資料驗證有區別 realSheet.addValidationData(validation);
            realSheet.addValidationData(validation);
        }

        return wb;
    }


根據路徑建立Excel

/** 
     * 根據路徑建立Excel 
     * @param workbook 
     * @param path 
     */  
    public void createExcel(Workbook workbook, String path) {  
        FileOutputStream fileOut = null;  
        try {  
            fileOut = new FileOutputStream(path);  
            workbook.write(fileOut);  
        } catch (Exception e) {  
            logger.error("Error create excel: ", e.getMessage());  
        } finally {  
            try {  
                if(fileOut != null) {  
                    fileOut.close();  
                }  
                  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }