Apache POI組件操作Excel,製作報表(二) .

 

本文接上一篇繼續探究POI組件的使用。 
    現在來看看Excel的基本設置問題,以2007爲例,先從工作簿來說,設置列寬,因爲生成表格列應該固定,而行是遍歷生成的,所以可以在工作簿級別來設置列寬,那麼可以如下來進行。 
    首先是創建工作簿和工作表了: 

		// 創建Excel2007工作簿對象
		XSSFWorkbook workbook2007 = new XSSFWorkbook();
		// 創建工作表對象並命名
		XSSFSheet sheet = workbook2007.createSheet("學生信息統計表");
之後是設置格式:
		// 設置行列的默認寬度和高度
		sheet.setColumnWidth(0, 32 * 80);// 對A列設置寬度爲80像素
		sheet.setColumnWidth(1, 32 * 80);
		sheet.setColumnWidth(2, 32 * 80);
		sheet.setColumnWidth(3, 32 * 80);
		sheet.setColumnWidth(4, 32 * 80);


 

 在這之前要先創建一個工作表sheet,然後就可以對每列設置列寬了。而行高一般針對不同的行有不同的設置,比如表頭行,合計行,數據行等,那麼分別設置會比較好。設置完列寬和行高,剩下就是對單元格的設置,比如居中,邊框,字體等。設置好樣式後將樣式應用於所需要的單元格,就得到了整體的效果,比如: 

// 創建樣式
		XSSFFont font = workbook2007.createFont();
		XSSFCellStyle headerStyle = workbook2007.createCellStyle();
		// 設置垂直居中
		headerStyle.setAlignment(HorizontalAlignment.CENTER);
		headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);
		// 設置邊框
		headerStyle.setBorderTop(BorderStyle.THIN);
		headerStyle.setBorderBottom(BorderStyle.THIN);
		headerStyle.setBorderLeft(BorderStyle.THIN);
		headerStyle.setBorderRight(BorderStyle.THIN);
		// 字體加粗
		font.setBold(true);
		// 設置長文本自動換行
		headerStyle.setWrapText(true);
		headerStyle.setFont(font);


這裏我們定義的是表頭的樣式,其中垂直居中時的設置要設置兩次,而且方法名不同,要注意。邊框就很簡單了,上下左右設置四次,字體加粗就是布爾值設定了,之後是文本自動換行,意思就是在固定單元格長度不變時是否自動折行。然後將字體樣式加入到單元格樣式中即可。 
    下面針對之前的例子設計表頭,如下:

// 創建表頭
		XSSFRow headerRow = sheet.createRow(0);
		headerRow.setHeightInPoints(25f);// 設置行高度
		XSSFCell nameHeader = headerRow.createCell(0);
		nameHeader.setCellValue("姓名");
		nameHeader.setCellStyle(headerStyle);
		XSSFCell genderHeader = headerRow.createCell(1);
		genderHeader.setCellValue("性別");
		genderHeader.setCellStyle(headerStyle);
		XSSFCell ageHeader = headerRow.createCell(2);
		ageHeader.setCellValue("年齡");
		ageHeader.setCellStyle(headerStyle);
		XSSFCell classHeader = headerRow.createCell(3);
		classHeader.setCellValue("班級");
		classHeader.setCellStyle(headerStyle);
		XSSFCell scoreHeader = headerRow.createCell(4);
		scoreHeader.setCellValue("成績");
		scoreHeader.setCellStyle(headerStyle);


 

 這裏的代碼會有大段的重複,因爲都是一個套路下來的,最後別忘加入樣式就行了,這樣表格頭部就做好了。剩下的是遍歷數據出行。 

for (int i = 0; i < studentList.size(); i++) {
			XSSFRow row = sheet.createRow(i + 1);
			row.setHeightInPoints(20f);
			Student student = studentList.get(i);
			XSSFCell nameCell = row.createCell(0);
			nameCell.setCellValue(student.getName());
			nameCell.setCellStyle(cellStyle);
			XSSFCell genderCell = row.createCell(1);
			genderCell.setCellValue(student.getGender());
			genderCell.setCellStyle(cellStyle);
			XSSFCell ageCell = row.createCell(2);
			ageCell.setCellValue(student.getAge());
			ageCell.setCellStyle(cellStyle);
			XSSFCell classCell = row.createCell(3);
			classCell.setCellValue(student.getSclass());
			classCell.setCellStyle(cellStyle);
			XSSFCell scoreCell = row.createCell(4);
			scoreCell.setCellValue(student.getScore());
			scoreCell.setCellStyle(cellStyle);
		}


用for循環就可以完成任務,需要注意的是循環變量仍然從0開始走,這是爲了遍歷集合的方便,而創建行就是從i+1開始走了,因爲0行是表頭,已經佔用了。下面就是先設定行高,之後開始取值,賦值,設定格式,結構也很統一。 
    完成遍歷後,來看看合併,Excel中的合併單元格也是很常用的操作,比如本例中,將班級都設置成一班後,那麼就想讓班級這列合併,該如何操作呢?

		// 合併班級
		sheet.addMergedRegion(new CellRangeAddress(1, 4, 3, 3));


這是對sheet級別的操作,因爲是在sheet上合併單元格,就是加一個合併的區域,這個區域接收四個參數,就是開始的行,結束的行,開始的列,結束的列,這個位置一般比較確定,或者用循環變量計算得出。班級,從第二行開始,第五行結束,對應索引是1,4,而列不變,就是在列上合併,就都是3即可。 
    至此我們已經將數據遍歷得出生成了Excel表格,設置了單元格樣式也進行了合併,那麼還有合計沒有說,用合計可以直接設置公式,也可以程序計算好後直接填充,後者一般用於比較複雜的報表,就不用在POI中設置合併的位置,減少複雜度。結合本例,我們來計算平均年齡和成績之和。如下: 

// 數據分析行
		int dadaRowNum = sheet.getLastRowNum();
		XSSFRow totalRow = sheet.createRow(dadaRowNum + 1);// 獲取已有的行數,加1再出新行
		totalRow.setHeightInPoints(25f);
		XSSFCell analyticsCell = totalRow.createCell(0);
		analyticsCell.setCellValue("數據分析");
		analyticsCell.setCellStyle(headerStyle);
		XSSFCell avgAgeCell = totalRow.createCell(1);
		avgAgeCell.setCellValue("平均年齡");
		avgAgeCell.setCellStyle(headerStyle);
		XSSFCell avgAgeValueCell = totalRow.createCell(2);
		avgAgeValueCell.setCellStyle(headerStyle);
		avgAgeValueCell.setCellFormula("AVERAGE(C2:C" + (dadaRowNum + 1) + ")");
		XSSFCell sumScoreCell = totalRow.createCell(3);
		sumScoreCell.setCellValue("總成績");
		sumScoreCell.setCellStyle(headerStyle);
		XSSFCell sumScoreValueCell = totalRow.createCell(4);
		sumScoreValueCell.setCellStyle(headerStyle);
		sumScoreValueCell.setCellFormula("SUM(E2:E" + (dadaRowNum + 1) + ")");


 

  這裏使用Excel函數的時候我們已經知道數據所在的位置,就直接使用了單元格的代號進行運算了,要注意使用公式時的方法中不用寫=號,POI會自動爲我們添加進去,這裏就直接寫公式的內容即可。在實際中可能會有動態計算的任務,那麼就根據業務複雜度來選擇是用Excel公式進行運算還是程序運算好後直接賦值顯示。 
    最後是生成文件的步驟,這已經介紹過了,都很簡單: 

				// 生成文件
		File file = new File(filePath);
		OutputStream os = null;
		try {
			os = new FileOutputStream(file);
			workbook2007.write(os);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
				}
			}
		}


 

 最後是執行測試了,寫個主函數來運行: 

public static void main(String[] args) {
		long start = System.currentTimeMillis();
		generateExcel2007(xlsx2007);
		long end = System.currentTimeMillis();
		System.out.println((end - start) + " ms done!");
	}


 

 將以上所有內容封裝在靜態方法generateExcel2007(String filePath)中,執行即可得到生成的Excel報表了,我們得到了這樣的一個報表: 

 

這就是最終得到的結果了。POI操作Excel的基本設置就基本涵蓋了,剩下的就是靈活運用,生成符合自己需求的報表了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章