1. 程式人生 > >Java用POI實現根據Excel表格模板生成新的Excel並實現資料輸出

Java用POI實現根據Excel表格模板生成新的Excel並實現資料輸出

一、

模板excel

結果excel

二、

專案所需jar包

poi-3.11-20141221.jar

poi-examples-3.11-20141221.jar

poi-excelant-3.11-20141221.jar

poi-ooxml-3.11-20141221.jar

poi-ooxml-schemas-3.11-20141221.jar

poi-scratchpad-3.11-20141221.jar

xmlbeans-2.6.0.jar

curvesapi-1.04.jar

三、專案原始碼

controller部分

	/**匯出到excel
	 * @param
	 * @throws Exception
	 */
	@RequestMapping(value="/excel")
	public ModelAndView exportExcel() throws Exception{
		logBefore(logger, Jurisdiction.getUsername()+"匯出Excel到excel");
		if(!Jurisdiction.buttonJurisdiction(menuUrl, "cha")){return null;}
		ModelAndView mv;
		//獲取頁面表單傳遞過來的引數
		PageData pd = this.getPageData();
		//dataMap作為model,存入資料
		Map<String,Object> dataMap = new HashMap<>();
		//儲存模板Excel路徑和生成Excel路徑
		List<String> urls=new ArrayList<>();
		//儲存所有heads
		List<String> heads=new ArrayList<>();
		//儲存尾部的數值
		List<String> tails=new ArrayList<>();
		//獲取當前日期
		Date date = new Date();
		//模板Excel檔案路徑
		//字尾為xls的檔案路徑
		String demoUrl=ExcelController.class.getClassLoader().getResource("reportxls/ExportExcel.xls").getPath().replaceFirst("/","");
		//按日期設定當前Excel表格的名字
		String fileName = Tools.date2Str(date, "yyyyMMddHHmmss");
		//生成Excel檔名稱
//		String excelUrl=fileName+".xlsx";
		//字尾為xlsx檔案的路徑
		String excelUrl=fileName+".xls";
		//將路徑新增到urls當中
		urls.add(demoUrl);
		urls.add(excelUrl);
		//將urls路徑存入到dataMap當中,作為model傳入到檢視中
		dataMap.put("urls",urls);
		//表格所需要的標題1
		String head1="標題1";
		//表格所需要的標題2
		String head2="標題2";
		//表格所需要的標題3
		String head3="標題3";
		//表格所需要的標題4
		String head4="標題4";
		//表格所需要的標題5
//		String head5="標題5";
		//存入這些標題
		heads.add(head1);
		heads.add(head2);
		heads.add(head3);
		heads.add(head4);
//		heads.add(head5);
		//表格所需要的尾部1
		String tail1="尾部1";
		//存入表格所需要的尾部
		tails.add(tail1);
		//表格所需要的尾部2
		String tail2="尾部2";
		//存入表格所需的尾部
		tails.add(tail2);
		//將tails存入到dataGrip中
		dataMap.put("tails",tails);
		//將標題存放到存入到dataGrip當中
		dataMap.put("heads",heads);
		//獲取當前Excel表格所需要的內容
		List<PageData> varOList = excelService.listAll(pd);
		dataMap.put("varOList",varOList);
		//建立需要渲染的Excel表格檢視
		//進行檔案字尾型別判斷
		if (demoUrl.endsWith(".xls")){
			XlsExcelView erv=new XlsExcelView();
			mv=new ModelAndView(erv,dataMap);
		}else {
			XlsxExcelView erv=new XlsxExcelView();
			mv=new ModelAndView(erv,dataMap);
		}
		return mv;
	}

檢視部分

public class XlsExcelView extends AbstractXlsView {
    @Override
    protected void buildExcelDocument(Map<String, Object> map, Workbook workbook, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {

        //獲取當前的urls地址
        List<String> urls=(List<String>)map.get("urls");
        //表格所要儲存的標題
        List<String> heads=(List<String>)map.get("heads");
        //表格所要儲存的尾部
        List<String> tails=(List<String>)map.get("tails");
        //獲取查詢到的結果集
        List<PageData> varOList=(List<PageData>)map.get("varOList");
        //獲取主表資訊
        PageData mainInfo=(PageData)map.get("mainInfo");
        //建立Excel檔案的輸入流物件
        FileInputStream fis=new FileInputStream(urls.get(0));
        //根據模板建立Excel工作簿
        workbook=new HSSFWorkbook(fis);
        //建立Excel檔案輸出流物件
        OutputStream out=httpServletResponse.getOutputStream();
        httpServletResponse.setContentType("application/octet-stream");
        httpServletResponse.setHeader("Content-Disposition","attachment;filename="+urls.get(1));

        //將workboo強轉成需要的HSSFBook
        HSSFWorkbook HSSFWorkbook=(HSSFWorkbook)workbook;
        //獲取建立工作簿的第一頁
        HSSFSheet sheet=HSSFWorkbook.getSheetAt(0);
        //給指定的sheet命名
        HSSFWorkbook.setSheetName(0,"dataSheet");
        //初始化當前的索引,設為當前sheet的最後一行行數
        int currentLastRowIndex=sheet.getLastRowNum();
        //儲存當前表格的樣式
        HSSFCellStyle cellStyle=HSSFWorkbook.createCellStyle();
        //獲取當前工作簿的行數
        int totalRows=sheet.getPhysicalNumberOfRows();
        /***********************遍歷模板sheet,根據當中的設定進行賦值*******************************************************************/
        for (int i=0;i<totalRows;i++){
            HSSFRow row=sheet.getRow(i);
            int column=row.getLastCellNum();
            //插入主表資訊
            if (mainInfo!=null){
                for (int j=0;j<mainInfo.size();j++){
                    HSSFCell cell=row.getCell(j)!=null?row.getCell(j):row.createCell(j);
                    String cellValue=cell.getStringCellValue();
                    if (cellValue.startsWith("#")){
                        String str=cellValue.replace("#","");
                        cell.setCellValue(mainInfo.get(str).toString());
                    }
                }

            }
            for (int j=0;j<column;j++){
                HSSFCell cell=row.getCell(j)!=null?row.getCell(j):row.createCell(j);
                String cellValue=cell.getStringCellValue();
                if (cellValue.startsWith("$")){
                    //設定新的單元格儲存的值
                    cell.setCellValue(heads.get(0));
                    heads.remove(0);
                }
                if (cellValue.startsWith("&")){
                    //取出表格的樣式,作為新插入單元格的樣式
                    cellStyle=cell.getCellStyle();
                    //獲取當前要插入記錄的行數
                    currentLastRowIndex=i;
                    continue;
                }
                if (cellValue.startsWith("#")){
                    cell.setCellValue(tails.get(0));
                    tails.remove(0);

                }

            }
        }
        //增加一行
        int lastRow=sheet.getLastRowNum()+1;
        sheet.setDefaultColumnWidth(lastRow);
        /*************************************************************************************************************/
        //在該行的進行插入(在刪除了特定行的欄位進行插入)
        int newRowIndex=currentLastRowIndex;
        //獲取模板對應的資料表字段的值
        HSSFRow dataRow=sheet.getRow(currentLastRowIndex);
        //獲得該行對應的欄位的數量
        int columnNum=dataRow.getPhysicalNumberOfCells();
        //根據生成欄位的單元格數量,生成對應數量的陣列
        String[] cells=new String[columnNum];
        //獲取資料集欄位的名稱,依次存入到cells陣列當中
        for (int i=0;i<columnNum;i++){
            HSSFCell cell=dataRow.getCell(i);
            //去掉&符號,並將從excel表格當中獲得的值統一轉換成大寫處理
            cells[i]=cell.getStringCellValue().replaceFirst("&","").toUpperCase();
        }
        //完成資料集欄位的收集後,刪除該段
        HSSFRow sprRow=sheet.getRow(currentLastRowIndex);
        sheet.removeRow(sprRow);
        /*************************插入新的行數********************************************/
        //將結果集渲染到當前sheet當中
        for (PageData pageData:varOList){
            sheet.shiftRows(newRowIndex,newRowIndex+1,1);
            HSSFRow newRow=sheet.createRow(newRowIndex++);
            //建立需要插入的目標行,該值需要在每次完成一行記錄值插入後重新歸0
            int cellIndex=0;
            //ic此處為cells陣列的結果集的欄位的位置
            for (int i=0;i<columnNum;i++){
                //從pageData當中取出目標單元格需要的值
                String cellContent=pageData.get(cells[i])!=null?pageData.get(cells[i]).toString():"";
                //設定目標單元格的位置和型別
                HSSFCell cell=newRow.createCell(cellIndex++,Cell.CELL_TYPE_STRING);
                //設定目標單元格的樣式
                cell.setCellStyle(cellStyle);
                //設定目標單元格的值
                cell.setCellValue(cellContent);
            }
        }

        /*********************************************************************************/

        HSSFWorkbook.write(out);
        fis.close();
        out.flush();
        out.close();

    }
}
附註:對於.xlsx檔案修改一下引用類名即可