1. 程式人生 > >java Excel表格生成工具類

java Excel表格生成工具類

最近做資料列表匯出成Excel表格,藉此機會學習了一下。

首先我們需要通過hibernate連結資料庫,將資料庫欄位對映成POJO實體,這裡不多做廢話。

我們需要用excel表格工具類,首先需要幾個poi的jar包,poi讀取excel資料所需要的jar包。其他的還需要一些commons-lang等語言包。

poi-3.9-20130828.jar

poi-ooxml-3.9-20130828.jar

poi-ooxml-schemas-3.9-20130828.jar

    Apache POI 是用Java編寫的免費開源的跨平臺的 Java API,Apache POI提供API給Java程式對Microsoft Office格式檔案讀和寫的功能。Apache POI 是建立和維護操作各種符合Office Open XML(OOXML)標準和微軟的OLE 2複合文件格式(OLE2)的Java API。用它可以使用Java讀取和建立,修改MS Excel檔案.而且,還可以使用Java讀取和建立MS Word和MSPowerPoint檔案。Apache POI 提供Java操作Excel解決方案(適用於Excel97-2008)。 下面我們來看一下Apache POI 中提供的幾大部分的作用:

HSSF - 提供讀寫Microsoft Excel XLS格式檔案的功能。  
XSSF - 提供讀寫Microsoft Excel OOXML XLSX格式檔案的功能。  
HWPF - 提供讀寫Microsoft Word DOC格式檔案的功能。  
HSLF - 提供讀寫Microsoft PowerPoint格式檔案的功能。  
HDGF - 提供讀Microsoft Visio格式檔案的功能。  
HPBF - 提供讀Microsoft Publisher格式檔案的功能。  
HSMF - 提供讀Microsoft Outlook格式檔案的功能。

1.ExcelCreater 建立Excel表格類

package com.yuanding.common.data.excel;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.yuanding.common.data.excel.ExcelFile.ExcelStyle;
import com.yuanding.common.util.Constants;


public class ExcelCreater {
	
	static {
		ExcelCreater.setFilePath(Constants.Path.DOC_PATH);
	}
	
	private String fullFileName;
	private static String filePath;
	private String title;
	private String sheetTitle;
	private String[] columnTitle;
	private String[] columnKey;
	private String[] columnWidth;
	private List<Map<String, Object>> data;

	public String getFullFileName() {
		return filePath + fullFileName;
	}

	public void setFullFileName(String fullFileName) {
		this.fullFileName = fullFileName;
	}
	
	public static String getFilePath() {
		return filePath;
	}

	public static void setFilePath(String filePath) {
		File file = new File(filePath);
		if(file.exists() && file.isDirectory()){
			ExcelCreater.filePath = filePath;			
		}else{
			ExcelCreater.filePath = System.getProperty("java.io.tmpdir");
		}
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String[] getColumnTitle() {
		return columnTitle;
	}

	public void setColumnTitle(String[] columnTitle) {
		this.columnTitle = columnTitle;
	}

	public String[] getColumnKey() {
		return columnKey;
	}

	public void setColumnKey(String[] columnKey) {
		this.columnKey = columnKey;
	}

	public String[] getColumnWidth() {
		return columnWidth;
	}

	public void setColumnWidth(String[] columnWidth) {
		this.columnWidth = columnWidth;
	}

	public List<Map<String, Object>> getData() {
		return data;
	}

	public void setData(List<Map<String, Object>> data) {
		this.data = data;
	}

	public String getSheetTitle() {
		return sheetTitle;
	}

	public void setSheetTitle(String sheetTitle) {
		this.sheetTitle = sheetTitle;
	}

	public boolean checkParam() {
		return fullFileName != null && columnTitle != null && columnKey != null;
	}

	public boolean create() {
		if (checkParam()) {
			ExcelFile excel = new ExcelFile();

			Map<String, String> sheetStyle = new HashMap<String, String>();
			sheetStyle.put(ExcelStyle.SHEET_HEAD, this.getTitle());
			sheetStyle.put(ExcelStyle.TITLE_HEIGHT, "500");
			sheetStyle.put(ExcelStyle.ROW_HEIGHT, "500");

			List<Map<String, String>> rowStyle = new ArrayList<Map<String, String>>();

			for (int i = 0, len = columnTitle.length; i < len; i++) {
				Map<String, String> styleItem1 = new HashMap<String, String>();
				styleItem1.put(ExcelStyle.CELL_TITLE, this.getColumnTitle()[i]);
				styleItem1.put(ExcelStyle.CELL_NAME, this.getColumnKey()[i]);
				styleItem1.put(ExcelStyle.CELL_WIDTH, this.getColumnWidth()[i]);
				rowStyle.add(styleItem1);
			}

			List<Map<String, Object>> sheetList = new ArrayList<Map<String, Object>>();

			Map<String, Object> sheet1 = new HashMap<String, Object>();
			sheet1.put(ExcelStyle.SHEET_LABEL, this.getSheetTitle());
			sheet1.put(ExcelStyle.SHEET_STYLE, sheetStyle);
			sheet1.put(ExcelStyle.ROW_STYLE, rowStyle);
			sheet1.put(ExcelStyle.DATA, this.getData());

			sheetList.add(sheet1);

			try {
				excel.write(filePath + fullFileName, sheetList);
				return true;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return false;
	}

}

2.ExcelFile Excel檔案工具類
package com.yuanding.common.data.excel;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 * Excel檔案工具
 * 類名: ExcelFile</br> 
 * 包名:com.diyvc.common.data.excel </br> 
 */
public class ExcelFile {
	
	public class ExcelStyle {
		public final static String CELL_NAME = "name";
		public final static String CELL_TITLE = "title";
		public final static String CELL_WIDTH = "width";
		
		public final static String ROW_STYLE = "row_style";
		public final static String ROW_HEIGHT = "row_height";
		
		public final static String SHEET_STYLE = "sheet_style";
		public final static String SHEET_LABEL = "sheet_title";
		public final static String SHEET_HEAD = "sheet_head";
		
		public final static String TITLE_HEIGHT = "title_height";
		
		public final static String DATA = "data";
	}
	
	private Font font;
	private CellStyle style;

	/*
	 * 構建標題單元格樣式
	 */
	private CellStyle getSheetTitleStyle(Workbook workbook) {
		// 設定表頭字型
		Font font = workbook.createFont();
		font.setFontName("宋體");
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		font.setFontHeight((short) 220);

		// 設定標題格式
		CellStyle style = workbook.createCellStyle();
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

		style.setFont(font);// 設定字型

		return style;
	}

	/*
	 * 構建表頭單元格樣式
	 */
	private CellStyle getColumnTitleStyle(Workbook workbook) {

		Font font = workbook.createFont();
		font.setFontName("宋體");
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		font.setFontHeight((short) 200);

		// 設定標題格式
		CellStyle style = workbook.createCellStyle();
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
		style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		style.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);

		// 設定邊框
		style.setBottomBorderColor(HSSFColor.BLACK.index);
		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
		style.setBorderTop(HSSFCellStyle.BORDER_THIN);

		style.setFont(font);// 設定字型

		return style;
	}

	/*
	 * 構建一般單元格樣式
	 */
	private CellStyle getCellStyle(Workbook workbook) {

		if (style == null) {
			// 設定字型
			font = workbook.createFont();
			font.setFontName("宋體");
			font.setFontHeight((short) 200);

			// 設定單元格格式
			style = workbook.createCellStyle();
			style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
			style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
			style.setWrapText(true);

			// 設定邊框
			style.setBottomBorderColor(HSSFColor.BLACK.index);
			style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
			style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
			style.setBorderRight(HSSFCellStyle.BORDER_THIN);
			style.setBorderTop(HSSFCellStyle.BORDER_THIN);

			style.setFont(font);// 設定字型
		}

		return style;
	}

	/**
	 * 建立Excel檔案
	 * 
	 * @param filename Excel檔案
	 * @param title Sheet標題
	 * @param style Sheet列格式(name: 列名稱,與data中資料對應, title:Sheet中顯示的標題,width:列寬度)
	 * @param data Sheet資料
	 */
	@SuppressWarnings("unchecked")
	public void write(String filename, List<Map<String, Object>> sheetList) throws Exception {

		Workbook workbook = new XSSFWorkbook();

		for (Map<String, Object> sheetMap : sheetList) {

			if (sheetMap != null && sheetMap.containsKey(ExcelStyle.SHEET_LABEL) && sheetMap.containsKey(ExcelStyle.ROW_STYLE)) {

				String sheetTitle = (String) sheetMap.get(ExcelStyle.SHEET_LABEL);

				Map<String, String> sheetStyle = sheetMap.containsKey(ExcelStyle.SHEET_STYLE) ? (Map<String, String>) sheetMap
						.get(ExcelStyle.SHEET_STYLE) : new HashMap<String, String>();
				List<Map<String, String>> rowStyle = (List<Map<String, String>>) sheetMap.get(ExcelStyle.ROW_STYLE);
				List<Map<String, Object>> data = (sheetMap.containsKey(ExcelStyle.DATA)) ? (List<Map<String, Object>>) sheetMap
						.get(ExcelStyle.DATA) : new ArrayList<Map<String, Object>>();

				Sheet sheet = workbook.createSheet(sheetTitle);

				List<String> columnNameList = new ArrayList<String>();
				List<String> columnTitleList = new ArrayList<String>();
				List<Integer> columnWidthList = new ArrayList<Integer>();

				for (Map<String, String> styleItem : rowStyle) {
					if (styleItem.containsKey(ExcelStyle.CELL_NAME)) {
						columnNameList.add(styleItem.get(ExcelStyle.CELL_NAME));
					}
					if (styleItem.containsKey(ExcelStyle.CELL_TITLE)) {
						columnTitleList.add(styleItem.get(ExcelStyle.CELL_TITLE));
					}
					if (styleItem.containsKey(ExcelStyle.CELL_WIDTH)) {
						String width = styleItem.get(ExcelStyle.CELL_WIDTH);
						if (StringUtils.isNumeric(width)) {
							columnWidthList.add(Integer.parseInt(width));
						}
					}
				}

				createTitle(workbook, sheet, sheetTitle, sheetStyle, columnNameList, columnTitleList, columnWidthList);

				//設定行高
				short rowHeight = 300;
				if (sheetStyle.containsKey(ExcelStyle.ROW_HEIGHT)) {
					rowHeight = Short.parseShort(sheetStyle.get(ExcelStyle.ROW_HEIGHT));
				}
				
				//設定行內容
				for (int i = 0; i < data.size(); i++) {
					Map<String, Object> item = data.get(i);

					if (item == null) {
						continue;
					}
					//構建內容行(2 包括標題欄和表頭)
					Row row = sheet.createRow(i + 2);
					row.setHeight(rowHeight);

					for (int j = 0; j < columnNameList.size(); j++) {
						Object value = item.containsKey(columnNameList.get(j)) ? item.get(columnNameList.get(j)) : "";

						Cell cell = row.createCell(j);

						cell.setCellStyle(getCellStyle(workbook));
						if (value instanceof Short || value instanceof Integer || value instanceof Long
								|| value instanceof Double) {
							cell.setCellValue(Double.parseDouble(value.toString()));
						} else if (value instanceof String) {
							cell.setCellValue(value.toString());
						} else if (value instanceof Date) {
							cell.setCellValue((Date) value);
						}

					}
				}
			}
		}

		OutputStream os = new FileOutputStream(filename);
		workbook.write(os);
		os.close();
	}

	/*
	 * 構建表頭
	 * 
	 * @param sheet 構建的表格
	 */
	private void createTitle(Workbook workbook, Sheet sheet, String sheetTitle, Map<String, String> sheetStyle, List<String> columnNameList,
			List<String> columnTitleList, List<Integer> columnWidthList) {
		
		//設定標題欄高
		short titleHeight = 300;
		if (sheetStyle.containsKey(ExcelStyle.TITLE_HEIGHT)) {
			titleHeight = Short.parseShort(sheetStyle.get(ExcelStyle.TITLE_HEIGHT));
		}
		//設定標題內容
		String sheetHead = sheetTitle;
		if (sheetStyle.containsKey(ExcelStyle.SHEET_HEAD)) {
			sheetHead = sheetStyle.get(ExcelStyle.SHEET_HEAD);
		}
		
		//設定表頭高
		short rowHeight = 300;
		if (sheetStyle.containsKey(ExcelStyle.ROW_HEIGHT)) {
			rowHeight = Short.parseShort(sheetStyle.get(ExcelStyle.ROW_HEIGHT));
		}
		
		
		//構建標題欄
		Row sheetTitleRow = sheet.createRow(0);
		sheetTitleRow.setHeight(titleHeight);

		// 合併標題欄
		sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, columnNameList.size() - 1));

		Cell cell = sheetTitleRow.createCell(0);
		cell.setCellStyle(getSheetTitleStyle(workbook));
		cell.setCellValue(sheetHead);

		//構建表頭
		Row columnTitleRow = sheet.createRow(1);
		columnTitleRow.setHeight(rowHeight);

		for (int i = 0; i < columnTitleList.size(); i++) {
			cell = columnTitleRow.createCell(i);
			cell.setCellStyle(getColumnTitleStyle(workbook));
			cell.setCellValue(columnTitleList.get(i));
		}

		for (int i = 0; i < columnWidthList.size(); i++) {
			sheet.setColumnWidth(i, columnWidthList.get(i));
		}
	}

	/**
	 * 讀取Excel檔案
	 * 
	 * @param filename Excel檔名
	 * @param sheetIndex Sheet編號(起始為0)
	 * @param titleRow 標題列的高度(如果為0,則表明沒有標題行)
	 * @param columns 列名
	 * 
	 * @return 讀取後的Excel資料
	 */
	public List<Map<String, Object>> read(String filename, int sheetIndex, int titleRow, String[] columns) {
		InputStream fileStream = null;
		try {
			fileStream = new FileInputStream(filename);
			if (filename.endsWith("xlsx")) {
				return this.read(fileStream, sheetIndex, titleRow, columns);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally{
			IOUtils.closeQuietly(fileStream);
		}
		return null;
	}
	
	/**
	 * 讀取Excel檔案
	 * 
	 * @param fileStream Excel檔案流
	 * @param sheetIndex Sheet編號(起始為0)
	 * @param titleRow 標題列的高度(如果為0,則表明沒有標題行)
	 * @param columns 列名
	 * 
	 * @return 讀取後的Excel資料
	 */
	public List<Map<String, Object>> read(InputStream fileStream, int sheetIndex, int titleRow, String[] columns) {
		List<Map<String, Object>> table = new ArrayList<Map<String, Object>>();
		try {
		Workbook wb = new XSSFWorkbook(fileStream);
		Sheet sheet = wb.getSheetAt(sheetIndex);

		int rowCount = 0;

		Iterator<Row> rows = sheet.iterator();
		while (rows.hasNext()) {
			Row row = rows.next();
			rowCount++;
			//過濾標題行
			if (titleRow >= rowCount) {
				continue;
			}
			Map<String, Object> item = new HashMap<String, Object>();
			for (int i = 0; i < columns.length; i++) {
				item.put(columns[i], getCellValue(row, i));
			}
			table.add(item);
		}
		IOUtils.closeQuietly(fileStream);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(fileStream);
		}
		return table;
	}

	private Object getCellValue(Row row, int index) {
		Cell cell = row.getCell(index);
		Object value = null;
		if (cell instanceof XSSFCell) {
			XSSFCell xssfCell = (XSSFCell) cell;
			if (xssfCell.getCellType() == XSSFCell.CELL_TYPE_NUMERIC) {
				if(HSSFDateUtil.isCellDateFormatted(xssfCell)){
					value = xssfCell.getDateCellValue();
				}else{
					value = (int) xssfCell.getNumericCellValue();
				}
			} else if (xssfCell.getCellType() == XSSFCell.CELL_TYPE_STRING) {
				value = xssfCell.getStringCellValue();
			}
		}

		return value;
	}

}

3.contants檔案配置類
package com.yuanding.common.util;


public class Constants {

	
	public static class Path{
		//檔案路徑
		public final static String DOC_PATH = Configure.values("doc_path");
		
		public final static String FILE_PATH = Configure.values("file_path");
		
		public final static String PRODUCT_PATH = Configure.values("product_path");
		//IP純真資料庫的檔名   所在資料夾路徑 (需修改)IpToAdd.Dat
		public static final String IP_ADDRESS_FILE_NAME = "IpToAdd.Dat";
		public static final String IP_ADDRESS_FILE_PATH =Configure.values("ip_path");
	}
}
4.匯出excel檔案類
/**
	* 方法名:園區資訊-匯出
	* 詳述:匯出園區資訊資料
	* @param response
	* @param request 說明引數含義
	* @return void說明返回值含義
	* @throws 說明發生此異常的條件
	 */
	@ResponseBody
	@RequestMapping(value = "/export",method = {RequestMethod.POST,RequestMethod.GET})
	public void exportDataExcel(HttpServletResponse response,HttpServletRequest request){
		try{
			Map<String, Object> properties = new HashMap<String, Object>();
			//園區名稱
			String parkName = request.getParameter("parkName");
			//根據使用者名稱查詢
			if(StringUtils.isNotBlank(parkName)) {
				properties.put("name:like", parkName);
			}
			List<PakParkInfo> list = parkBiz.findPage(null, properties);
			if(list.size()>0){
				//組裝匯出陣列
				List<Map<String, Object>> eclist = new ArrayList<Map<String,Object>>();
				Date date=new Date();
				String now=DateUtil.parseDateToStr(date, DateUtil.DATE_TIME_FORMAT_YYYYMMDDHHMISSSSS);
				String fileName=now+"園區列表資料.xlsx";
				//表格資訊
				ExcelCreater ec = new ExcelCreater();
				ec.setFullFileName(fileName);
				ec.setTitle("園區列表資料");
				ec.setSheetTitle("sheet1");
				ec.setColumnTitle(new String[] { "園區名稱", "責任人", "手機號" ,"地址","入駐企業數","建立時間"});//設定表頭
				ec.setColumnKey(new String[] { "name", "contacts", "cellphone","address","enterpriseNum","createTime"});//設定key
				ec.setColumnWidth(new String[] { "5000","5000","5000","15000","3000","10000"});//設定列寬
				for(PakParkInfo pakParkInfo :list){
					Map<String, Object > ecmap = new HashMap<String, Object>();
					ecmap.put("name", pakParkInfo.getName());
					ecmap.put("contacts", pakParkInfo.getContacts());
					ecmap.put("cellphone", pakParkInfo.getCellphone());
					ecmap.put("address", pakParkInfo.getAddress());
					ecmap.put("enterpriseNum", pakParkInfo.getEnterpriseInfoList().size());
					ecmap.put("createTime", DateUtil.parseDateToStr(pakParkInfo.getCreateTime(), DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS));
					eclist.add(ecmap);
				}
				//設定表格列表資訊
				ec.setData(eclist);
				//判斷表格是否建立成功
				if(ec.create()){
					InputStream fis = null;
					byte[] buffer = null;
					OutputStream os = null;
					try{
			    	    fis = new BufferedInputStream(new FileInputStream(ec.getFullFileName()));
			    	    buffer = new byte[fis.available()];
			    	    fis.read(buffer);
			    	    response.reset();
			    	    // 先去掉檔名稱中的空格,然後轉換編碼格式為utf-8,保證不出現亂碼,這個檔名稱用於瀏覽器的下載框中自動顯示的檔名
						response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.replaceAll(" ", "").getBytes("utf-8"),"iso8859-1"));
			     	    os =  response.getOutputStream();
			     	    response.setContentType("application/octet-stream");
				   	    os.write(buffer);// 輸出檔案
				   	    os.flush();
					}catch (Exception e) {
						e.printStackTrace();
					}finally{
						try {
							fis.close();
							os.close();
							System.out.print("匯出檔案-----------");
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}

上面的程式碼是我們先獲取實體,通過物件中的資料拿到我們想要的欄位,將資料儲存到集合中

待編輯。。。