Excel導出工具

調用方法必要參數:

( HttpServletRequest request, HttpServletResponse response )

調用代碼:

List<Map<String, Object>> list = 數據庫查詢結果 //TODO
ExcelUtil excelUtil = new ExcelUtil();
LinkedHashMap<String, String> keyMap = new LinkedHashMap<String, String>();
keyMap.put("字段名1", "導出結果tittle1");//TODO
keyMap.put("字段名2", "導出結果tittle2");		
String title = "導出文件名".concat(DateUtils.formatDateToString(new Date(), DateUtils.YYYYMMDDHHMMSS));//TODO
title = excelUtil.encodeFileName(title, request);
excelUtil.dlExcelUtil(response, list, keyMap, title);

工具類:ExcelUtil 

package *****.common.utils.excel;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
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.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import jxl.CellView;
import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.VerticalAlignment;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

public class ExcelUtil {

	public static final int RESULT_SUCC = 0;
	public static final int RESULT_FAIL = -1;

	public static final String TYPE_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

	/**
	 * 將數據轉成成excel。 特性: 1、將時間類型的值轉成yyyy-MM-dd HH:mm:ss 2、將數字類型的值轉成帶千分符的形式,並右對齊
	 * 3、除數字類型外,其他類型的值居中顯示
	 * 
	 * @param keyMap
	 *            定義標題及每一列對應的JavaBean屬性。標題的先後順序,對應keyMap的插入順序;
	 *            map中的key值爲JavaBean屬性,value爲標題
	 * @param listContent
	 *            表格內容,List中的每一個元素,對應到excel的每一行
	 * @param os
	 *            結果輸出流
	 * @return
	 */
	public final int export(LinkedHashMap<String, String> keyMap, List<Map<String, Object>> listContent,
			OutputStream os) {

		int rs = RESULT_SUCC;
		try {
			// 創建工作簿
			WritableWorkbook workbook = Workbook.createWorkbook(os);

			// 創建名爲sheet1的工作表
			WritableSheet sheet = workbook.createSheet("Sheet1", 0);

			// 設置字體
			WritableFont NormalFont = new WritableFont(WritableFont.ARIAL, 12);
			WritableFont BoldFont = new WritableFont(WritableFont.ARIAL, 12, WritableFont.BOLD);

			// 標題居中
			WritableCellFormat titleFormat = new WritableCellFormat(BoldFont);
			titleFormat.setBorder(Border.ALL, BorderLineStyle.THIN); // 線條
			titleFormat.setVerticalAlignment(VerticalAlignment.CENTRE); // 文字垂直對齊
			titleFormat.setAlignment(Alignment.CENTRE); // 文字水平對齊
			titleFormat.setWrap(false); // 文字是否換行

			// 正文居中
			WritableCellFormat contentCenterFormat = new WritableCellFormat(NormalFont);
			contentCenterFormat.setBorder(Border.ALL, BorderLineStyle.THIN);
			contentCenterFormat.setVerticalAlignment(VerticalAlignment.CENTRE);
			contentCenterFormat.setAlignment(Alignment.CENTRE);
			contentCenterFormat.setWrap(false);

			// 正文右對齊
			WritableCellFormat contentRightFormat = new WritableCellFormat(NormalFont);
			contentRightFormat.setBorder(Border.ALL, BorderLineStyle.THIN);
			contentRightFormat.setVerticalAlignment(VerticalAlignment.CENTRE);
			contentRightFormat.setAlignment(Alignment.RIGHT);
			contentRightFormat.setWrap(false);

			// 設置標題,標題內容爲keyMap中的value值,標題居中粗體顯示
			Iterator titleIter = keyMap.entrySet().iterator();
			int titleIndex = 0;
			while (titleIter.hasNext()) {
				Map.Entry<String, String> entry = (Map.Entry<String, String>) titleIter.next();
				sheet.addCell(new Label(titleIndex++, 0, entry.getValue(), titleFormat));
			}

			// 設置正文內容
			for (int i = 0; i < listContent.size(); i++) {
				Iterator contentIter = keyMap.entrySet().iterator();
				int colIndex = 0;
				int listIndex = 0;
				while (contentIter.hasNext()) {
					Map.Entry<String, String> entry = (Map.Entry<String, String>) contentIter.next();
					Object key = entry.getKey();

					// Field field =
					// listContent.get(i).getClass().getDeclaredField(key.toString());
					// field.setAccessible(true);
					// Object content = field.get(listContent.get(i));

					String contentStr = "";

					Map haha = (Map) listContent.get(i);
					if (haha.get(key.toString()) != null && haha.get(key.toString()).toString() != "") {
						contentStr = haha.get(key.toString()).toString();
					}

					// if (null != content) {
					// contentStr = content.toString();
					// }

					// if (isNumberic(field)) {
					// 如果正文內容是數字,要轉換成千分符形式,右對齊
					// sheet.addCell(new Label(colIndex++, i + 1,
					// getNumbericValue(contentStr), contentRightFormat));
					// } else {

					// 如果是時間類型,統一做格式化。
					// String timeStr = getTimeFormatValue(field, content);
					// if (null != timeStr && !timeStr.trim().equals("")) {
					// contentStr = timeStr;
					// } else {
					// 不是時間類型的值,不用轉換
					// }

					sheet.addCell(new Label(colIndex++, i + 1, contentStr, contentCenterFormat));
				}

			}

			// }

			// 寬度自適應。能夠根據內容增加寬度,但對中文的支持不好,如果內容中包含中文,會有部分內容被遮蓋
			for (int i = 0; i < keyMap.size(); i++) {
				CellView cell = sheet.getColumnView(i);
				cell.setAutosize(true);
				sheet.setColumnView(i, cell);
			}
			workbook.write();
			workbook.close();

		} catch (Exception e) {
			rs = RESULT_FAIL;
			e.printStackTrace();
		}
		return rs;
	};

	/**
	 * 設置單元格的邊框(先執行Start方法)
	 * 
	 * @param sheetIndex
	 *            Excel索引,從0開始
	 * @param startRow
	 *            開始行,從0開始
	 * @param rowNum
	 *            設置的行數
	 * @param startCol
	 *            開始列,從0開始
	 * @param colNum
	 *            需要設置的列數
	 * @throws Exception
	 */
	public void setBorder(int sheetIndex, int startRow, int rowNum, int startCol, int colNum, SXSSFWorkbook workbook,
			OutputStream os) throws Exception {
		try {
			Sheet sheet = workbook.getSheetAt(sheetIndex);
			// 設置單元格樣式
			for (int rIndex = startRow; rIndex < startRow + rowNum; rIndex++) {
				Row row = sheet.getRow(rIndex);
				if (row == null) {
					row = sheet.createRow(rIndex);
				}
				for (int cIndex = startCol; cIndex < startCol + colNum; cIndex++) {
					Cell cell = row.getCell(cIndex);
					if (cell == null) {
						cell = row.createCell(cIndex);
					}

					CellStyle style = cell.getCellStyle();
					// 判斷是否已經創建過
					if (style.getIndex() == 0) {
						style = workbook.createCellStyle();
					}
					style.setBorderBottom(CellStyle.BORDER_THIN);
					style.setBorderLeft(CellStyle.BORDER_THIN);
					style.setBorderRight(CellStyle.BORDER_THIN);
					style.setBorderTop(CellStyle.BORDER_THIN);
					cell.setCellStyle(style);
				}
			}

			// 寫入文件,採用分批寫入的方式進行寫入
			// workbook.write(os);
			// workbook.close();
		} catch (Exception e) {
			throw new Exception(String.format("setBorder:%s", e.getMessage()));
		}
	}

	/**
	 * 設置列自適應(先執行Start方法)
	 * 
	 * @param sheetIndex
	 *            Sheet的索引,從0開始
	 * @param startCol
	 *            開始列,從0開始
	 * @param colNum
	 *            列數量
	 * @throws Exception
	 */
	public void setAutoFit(int sheetIndex, int startCol, int colNum, SXSSFWorkbook workbook, OutputStream os)
			throws Exception {
		try {
			Sheet sheet = workbook.getSheetAt(sheetIndex);
			for (int cIndex = startCol; cIndex < startCol + colNum; cIndex++) {
				sheet.autoSizeColumn(cIndex);
			}

			// 寫入文件,採用分批寫入的方式進行寫入
			// workbook.write(os);
			// workbook.close();
		} catch (Exception e) {
			throw new Exception(String.format("setAutoFit:%s", e.getMessage()));
		}
	}

	/**
	 * 設置單元格的值,支持/n自動換行(先執行Start方法)
	 * 
	 * @param sheetIndex
	 *            Sheet的索引,從0開始
	 * @param row
	 *            行索引
	 * @param col
	 *            列索引
	 * @param value
	 *            值(暫時只支持字符串)
	 * @throws Exception
	 */
	public void setWrapCellData(int sheetIndex, int row, int col, String value, SXSSFWorkbook workbook, OutputStream os)
			throws Exception {
		try {
			Sheet sheet = workbook.getSheetAt(sheetIndex);

			Row mRow = sheet.getRow(row);
			if (mRow == null) {
				mRow = sheet.createRow(row);
			}
			Cell mCell = mRow.createCell(col);
			mCell.setCellValue(value);
			// 設置自動換行
			CellStyle style = workbook.createCellStyle();
			style.setWrapText(true);
			mCell.setCellStyle(style);

			// 寫入文件,採用分批寫入的方式進行寫入
			// workbook.write(os);
			// workbook.close();
		} catch (Exception e) {
			throw new Exception(String.format("setWrapCellData:%s", e.getMessage()));
		}
	}

	/**
	 * 將數據轉成成excel。 特性: 1、將時間類型的值轉成yyyy-MM-dd HH:mm:ss 2、將數字類型的值轉成帶千分符的形式,並右對齊
	 * 3、除數字類型外,其他類型的值居中顯示
	 * 
	 * @param titleMap
	 *            定義標題及每一列對應的JavaBean屬性。標題的先後順序,對應keyMap的插入順序;
	 *            map中的key值爲JavaBean屬性,value爲標題
	 * @param freezeParams
	 *            凍結列,必須是長度爲4的整數數組。可以爲空。
	 * @param datas
	 *            表格內容,List中的每一個元素,對應到excel的每一行
	 * @param outputStream
	 *            結果輸出流
	 * @return
	 */
	public final int exportMorUtil(LinkedHashMap<String, String> titleMap, Integer[] freezeParams,
			List<Map<String, Object>> datas, OutputStream outputStream) {
		SXSSFWorkbook workbook = null;
		try {
			workbook = new SXSSFWorkbook(1000); // 這裏1000是在內存中的數量,如果大於此數量時,會寫到硬盤,以避免在內存導致內存溢出
			SXSSFSheet sheet = workbook.createSheet();
		    sheet.trackAllColumnsForAutoSizing(); // 自動調整列寬
			if (datas != null) {

				CellStyle titleStyle = workbook.createCellStyle();
				titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
				titleStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
				titleStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
				titleStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
				titleStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
				titleStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); 
				titleStyle.setFillForegroundColor(HSSFColor.WHITE.index); 

				CellStyle centerStyle = workbook.createCellStyle();
				centerStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
				centerStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
				centerStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
				centerStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);

				CellStyle numberStyle = workbook.createCellStyle();
				numberStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
				numberStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
				numberStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);

				Iterator<Entry<String, String>> titleIter = titleMap.entrySet().iterator();
				int titleIndex = 0;
				Row row = sheet.createRow(0);
				while (titleIter.hasNext()) {
					Cell cell = row.createCell(titleIndex);
					Map.Entry<String, String> entry = (Map.Entry<String, String>) titleIter.next();
					cell.setCellValue(entry.getValue());
					cell.setCellStyle(titleStyle);
					sheet.autoSizeColumn(titleIndex);
					titleIndex++;
//					System.out.println(">>>[" + entry.getValue() + "]<<<");
				}
				sheet.createFreezePane(0, 1); // 固定表頭
				for (int rownum = 1; rownum <= datas.size(); rownum++) {
					row = sheet.createRow(rownum);
					Iterator<Entry<String, String>> contentIter = titleMap.entrySet().iterator();
					int colIndex = 0;
					while (contentIter.hasNext()) {
						Cell cell = row.createCell(colIndex);
						Map.Entry<String, String> entry = (Map.Entry<String, String>) contentIter.next();
						String key = (String) entry.getKey();
						Map<String, Object> haha = (Map<String, Object>) datas.get(rownum - 1);
						Object value = haha.get(key);
						if (value != null) {
							if (value instanceof Double) {
								cell.setCellValue((Double) value);
								cell.setCellStyle(numberStyle);
							} else if (value instanceof Integer) {
								cell.setCellValue((Integer) value);
								cell.setCellStyle(numberStyle);
							} else if (value instanceof Long) {
								cell.setCellValue((Long) value);
								cell.setCellStyle(numberStyle);
							} else if (value instanceof BigDecimal) {
								cell.setCellValue(((BigDecimal) value).doubleValue());
								cell.setCellStyle(numberStyle);
							} else {
								cell.setCellValue(value.toString());
								cell.setCellStyle(centerStyle);
								if (!(value instanceof String)) {
									System.out.println(">>>>>>>>>> value instanceof " + value.getClass());
								}
							}
						} else {
							cell.setCellValue("");
							cell.setCellStyle(centerStyle);
						}
						colIndex++;
					}
				}

				int index = titleMap.size();
				while (index-- > 0) {
					sheet.autoSizeColumn(index);
				}

				if (freezeParams != null) {
					sheet.createFreezePane(freezeParams[0], freezeParams[1], freezeParams[2], freezeParams[3]);
				}
			}
			workbook.write(outputStream);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (workbook != null) {
				try {
					workbook.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return 1;
	};

	/**
	 * 判斷當前屬性是否爲數字類型
	 * 
	 * @param field
	 * @return
	 */
	public static boolean isNumberic(Field field) {
		if (field.getType().getName().equals(java.lang.Integer.class.getName())
				|| field.getType().getName().equals("int")
				|| field.getType().getName().equals(java.lang.Long.class.getName())
				|| field.getType().getName().equals("long")
				|| field.getType().getName().equals(java.lang.Double.class.getName())
				|| field.getType().getName().equals("double")) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 獲取格式化後的時間串
	 * 
	 * @param field
	 * @param content
	 * @return
	 */
	public String getTimeFormatValue(Field field, Object content) {
		String timeFormatVal = "";
		if (field.getType().getName().equals(java.sql.Timestamp.class.getName())) {
			Timestamp time = (Timestamp) content;
			timeFormatVal = longTimeTypeToStr(time.getTime(), TYPE_YYYY_MM_DD_HH_MM_SS);
		} else if (field.getType().getName().equals(java.util.Date.class.getName())) {
			Date time = (Date) content;
			timeFormatVal = longTimeTypeToStr(time.getTime(), TYPE_YYYY_MM_DD_HH_MM_SS);
		}

		return timeFormatVal;
	}

	/**
	 * 獲取千分位數字
	 * 
	 * @param str
	 * @return
	 */
	public String getNumbericValue(String str) {
		String numbericVal = str;
		try {
			Double doubleVal = Double.valueOf(str);
			numbericVal = DecimalFormat.getNumberInstance().format(doubleVal);
		} catch (NumberFormatException e) {
			// if exception, not format
		}
		return numbericVal;
	}

	/**
	 * 格式化時間
	 * 
	 * @param time
	 * @param formatType
	 * @return
	 */
	public String longTimeTypeToStr(long time, String formatType) {

		String strTime = "";
		if (time >= 0) {
			SimpleDateFormat sDateFormat = new SimpleDateFormat(formatType);

			strTime = sDateFormat.format(new Date(time));

		}

		return strTime;

	}

	public void dlExcelUtil(HttpServletResponse response,
			List<Map<String, Object>> transferInfoList, LinkedHashMap<String, String> titileMap, String fileName) throws IOException {
		this.dlExcelUtil(response, transferInfoList, titileMap, null, fileName);
	}

	public void dlExcelUtil(HttpServletResponse response,
			List<Map<String, Object>> transferInfoList, LinkedHashMap<String, String> titileMap, Integer[] freezeParams,
			String fileName) throws IOException {
		long start = System.currentTimeMillis();
		OutputStream out = response.getOutputStream();
//		Date d = new Date();
//		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//		String time = formatter.format(d);
//		fileName += time;
		response.reset();// 清空輸出流
		response.setHeader("Content-disposition", "attachment; filename=" + toUtf8String(fileName) + ".xlsx");// 設定輸出文件頭
		response.setContentType("application/msexcel;charset=UTF-8");// 定義輸出類型
		// this.export(titileMap, transferInfoList, out);
		this.exportMorUtil(titileMap, freezeParams, transferInfoList, out);
		long end = System.currentTimeMillis();
		System.out.println(end - start);
	}
	
	public String encodeFileName(String fileNames, HttpServletRequest request) {
        String codedFilename = null;
        try {
            String agent = request.getHeader("USER-AGENT");
            if (null != agent && -1 != agent.indexOf("MSIE") || null != agent && -1 != agent.indexOf("Trident") || null != agent && -1 != agent.indexOf("Edge")) {// ie瀏覽器及Edge瀏覽器
                String name = java.net.URLEncoder.encode(fileNames, "UTF-8");
                codedFilename = name;
            } else if (null != agent && -1 != agent.indexOf("Mozilla")) {
                // 火狐,Chrome等瀏覽器
                codedFilename = new String(fileNames.getBytes("UTF-8"), "iso-8859-1");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return codedFilename;
    }

	public static String toUtf8String(String s) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (c >= 0 && c <= 255) {
				sb.append(c);
			} else {
				byte[] b;
				try {
					b = Character.toString(c).getBytes("utf-8");
				} catch (Exception ex) {
					System.out.println(ex);
					b = new byte[0];
				}
				for (int j = 0; j < b.length; j++) {
					int k = b[j];
					if (k < 0)
						k += 256;
					sb.append("%" + Integer.toHexString(k).toUpperCase());
				}
			}
		}
		return sb.toString();
	}

}

 

發佈了28 篇原創文章 · 獲贊 4 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章