Java模板導出Excel

爲什麼使用Apache POI 框架導出Excel?

POI 是Apache 基於Java語言頂級開源項目,功能強大,穩定,符合Office openXML規範,入門簡單 。

能夠處理Microsoft office 大多數文件。如:Word , Excel , PowerPoint。加上Apache的光環,所以是不二之選。

JXL是一套提供對Excel操作的類庫,操作效率低,功能較爲單一,對函數表達式,導出圖片支持不好。

 

爲什麼爲封裝此工具類?

由於公司供應鏈部門業務需要,對Excel處理這塊有較爲嚴苛的要求。爲了使導出的Excel保持統一的風格和提高開發效率,從實際項目出發封裝了通用自定義導出Excel工具類。

    基於POI 3.9 版本,建議讀者在使用該工具類的時候升級爲最新版本,最新版本對以前老版本的一些Bug做了修復,性能會更好。

   此工具類只支持Offece 2007 及以上版本,如果讀者要支持2003版本可以對該工具類進行擴展。

功能概述

  1. 支持在任意位置填充字符,數字,圖片
  2. 支持在任意位置填充一行值
  3. 支持在任意位置填充列表值
  4. 支持設置列寬,行高
  5. 支持在任意位置填充標題
  6. 支持自定義單元格樣式風格

 

效果預覽

1. 定義模板

2.添加模板到項目模板目錄

3.執行填充邏輯,生成Excel

填充列表效果:

設計思想

設計原則:簡單易用。由於導出模板的多樣性和不確定性,則需要封裝常用的數據結構和樣式風格,由開發人員根據業務需求對數據進行組裝填充模板,滿足業務需求。

採用策略模式,符合開閉原則。

對象關係

 

 

對象 說明
ExportExcelCustom 自定義導出接口類,封裝了常用導出excel方式
ExportExcelCustomXlsx xlsx格式excel導出實現
AbstractExcelData 數據實體抽象基類,抽象通用數據字段
ExcelConfigExt 擴展配置實體,用於擴展其它功能傳遞參數
ExcelTextData  單列內容實體,支持字符,數字,時間
ExcelTitleData 列表標題實體,支持自定義風格
ExcelRowSignData 單行內容實體
ExcelRowMultiData 列表內容實體
ExcelPictureData 圖片內容實體
ExcelFontEnum 通用字體樣式枚舉
ExcelStyleEnum 通用樣式枚舉

使用注意點

由於操作Excel文件一般較大,建議對JVM調優,將大對象直接放在老年代,具體調優方式,網上資料很多。

待優化點

沒有采用annation的方式

待擴充功能點

1. 基於模板導出,導出一個對象,使用表達式,自動填充字段名(不需要指定%s)支持重複填充

2. 導出一個list自動填充一個列表

3. 樣式擴展優化(列表標題自動固定樣式)

4.添加函數表達式

5. logo 添加

6. 單元格下拉選擇

7. 合併單元格

8. 由於該工具類使用JDK 1.7 ,可以升級到JDK1.8或JDK1.9 使用函數式變成和lambda進行代碼結構優化

有興趣的同學可以對此工具類進行擴展。

 

 

核心代碼

 

/**
 * @version V1.0
 * @Author: Vachel Wang
 * @Date: 2017/5/2
 * @Time: 下午8:19
 * @Description: 列的內容
 */
public abstract class AbstractExcelData {

    private Object data;
    private Integer rowIndex;
    private Integer colIndex;
    private Integer colWidth;
    private Integer rowHeight;
    private Integer sheetIndex;
    private ExportExcelCustom exportExcelCustom;
    private ExcelConfigExt excelConfigExt;

    private static final Logger LOG = LoggerFactory.getLogger(AbstractExcelData.class);

    /**
     * @param exportExcelCustom 處理Excel對象
     * @param data              數據
     * @param colIndex          列座標
     * @param rowIndex          行座標
     * @param colWidth          列寬
     * @param rowHeight         行高
     * @param sheetIndex        sheet下標
     * @param excelConfigExt    擴展配置
     */
    public AbstractExcelData(ExportExcelCustom exportExcelCustom, Object data, Integer colIndex, Integer rowIndex, Integer colWidth, Integer rowHeight, Integer sheetIndex, ExcelConfigExt excelConfigExt) {
        this.setExportExcelCustom(exportExcelCustom);
        this.setData(data);
        this.setRowIndex(rowIndex);
        this.setColIndex(colIndex);
        this.setColWidth(colWidth);
        this.setRowHeight(rowHeight);
        this.setSheetIndex(sheetIndex);
        if (excelConfigExt == null)
            excelConfigExt = new ExcelConfigExt();
        this.setExcelConfigExt(excelConfigExt);
    }

    public abstract void fillData();

    public Integer getSheetIndex() {
        return sheetIndex;
    }

    public void setSheetIndex(Integer sheetIndex) {
        this.sheetIndex = sheetIndex;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public Integer getRowIndex() {
        return rowIndex;
    }

    public void setRowIndex(Integer rowIndex) {
        this.rowIndex = rowIndex;
    }

    public Integer getColIndex() {
        return colIndex;
    }

    public void setColIndex(Integer colIndex) {
        this.colIndex = colIndex;
    }

    public Integer getColWidth() {
        return colWidth;
    }

    public void setColWidth(Integer colWidth) {
        this.colWidth = colWidth;
    }

    public Integer getRowHeight() {
        return rowHeight;
    }

    public void setRowHeight(Integer rowHeight) {
        this.rowHeight = rowHeight;
    }

    public ExportExcelCustom getExportExcelCustom() {
        return exportExcelCustom;
    }

    public void setExportExcelCustom(ExportExcelCustom exportExcelCustom) {
        this.exportExcelCustom = exportExcelCustom;
    }

    public ExcelConfigExt getExcelConfigExt() {
        return excelConfigExt;
    }

    public void setExcelConfigExt(ExcelConfigExt excelConfigExt) {
        this.excelConfigExt = excelConfigExt;
    }
}

 

/**
 * @Author: Vachel Wang
 * @Date: 2017/5/3下午7:42
 * @Version: V1.0
 * @Description: 設值font必須要在設值cellStyle之前
 */
public class ExcelConfigExt {
    // 新創建sheet名稱
    private String newSheetName;
    // 字體樣式
    private XSSFFont font;
    // 單元格樣式
    private XSSFCellStyle cellStyle;

    public String getNewSheetName() {
        return newSheetName;
    }

    public void setNewSheetName(String newSheetName) {
        this.newSheetName = newSheetName;
    }

    public XSSFFont getFont() {
        return font;
    }

    public void setFont(XSSFFont font) {
        this.font = font;
        if(this.cellStyle!=null){
            this.cellStyle.setFont(this.font);
        }
    }

    public XSSFCellStyle getCellStyle() {
        return cellStyle;
    }

    public void setCellStyle(XSSFCellStyle cellStyle) {
        this.cellStyle = cellStyle;
        this.cellStyle.setFont(font);
    }
}

 

/**
 * @Author: Vachel Wang
 * @Date: 2017/5/2
 * @Time: 下午8:27
 * @Version: V1.0
 * @Description: 圖片內容
 */
public class ExcelPictureData extends AbstractExcelData {
    /**
     * @param exportExcelCustom 處理Excel對象
     * @param data              數據內容
     * @param startColIndex     開始列座標
     * @param startRowIndex     開始行座標
     * @param endColIndex       結束列座標
     * @param endRowIndex       結束行座標
     * @param colWidth          列寬
     * @param rowHeight         行高
     * @param sheetIndex        sheet下標
     * @param excelConfigExt    擴展配置
     */
    public ExcelPictureData(ExportExcelCustom exportExcelCustom, byte[] data, int startColIndex, int startRowIndex, int endColIndex, int endRowIndex, Integer colWidth, Integer rowHeight, Integer sheetIndex, ExcelConfigExt excelConfigExt) {
        super(exportExcelCustom, data, startColIndex, startRowIndex, colWidth, rowHeight, sheetIndex, excelConfigExt);
        this.startColIndex = startColIndex;
        this.startRowIndex = startRowIndex;
        this.endColIndex = endColIndex;
        this.endRowIndex = endRowIndex;
    }

    private Integer startRowIndex;
    private Integer endRowIndex;
    private Integer startColIndex;
    private Integer endColIndex;

    public Integer getStartRowIndex() {
        return startRowIndex;
    }

    public void setStartRowIndex(Integer startRowIndex) {
        this.startRowIndex = startRowIndex;
        this.setRowIndex(startRowIndex);
    }

    public Integer getEndRowIndex() {
        return endRowIndex;
    }

    public void setEndRowIndex(Integer endRowIndex) {
        this.endRowIndex = endRowIndex;
    }

    public Integer getStartColIndex() {
        return startColIndex;
    }

    public void setStartColIndex(Integer startColIndex) {
        this.startColIndex = startColIndex;
        this.setColIndex(startColIndex);
    }

    public Integer getEndColIndex() {
        return endColIndex;
    }

    public void setEndColIndex(Integer endColIndex) {
        this.endColIndex = endColIndex;
    }

    @Override
    public void fillData() {
        this.getExportExcelCustom().fillPictureData(this);
    }
}

 

/**
 * @Author: Vachel Wang
 * @Date: 2017/5/2
 * @Time: 下午8:30
 * @Version: V1.0
 * @Description: 多行內容
 */
public class ExcelRowMultiData extends AbstractExcelData {

    /**
     * @param exportExcelCustom 處理excel對象
     * @param rowData           行內容
     * @param colIndex          列座標
     * @param rowIndex          行座標
     * @param colWidth          列寬
     * @param rowHeight         行高
     * @param sheetIndex        sheet下標
     * @param excelConfigExt    擴展配置
     */
    public ExcelRowMultiData(ExportExcelCustom exportExcelCustom, List<ArrayList<AbstractExcelData>> rowData, Integer colIndex, Integer rowIndex, Integer colWidth, Integer rowHeight, Integer sheetIndex, ExcelConfigExt excelConfigExt) {
        super(exportExcelCustom, rowData, colIndex, rowIndex, colWidth, rowHeight, sheetIndex, excelConfigExt);
    }

    @Override
    public void fillData() {
        this.getExportExcelCustom().fillRowMultiData(this);
    }
}

 

/**
 * @Author: Vachel Wang
 * @Date: 2017/5/2
 * @Time: 下午8:29
 * @Version: V1.0
 * @Description: 單行內容
 */
public class ExcelRowSignData extends AbstractExcelData {
    /**
     * @param exportExcelCustom 處理excel對象
     * @param rowData           數據內容
     * @param colIndex          填充列座標
     * @param rowIndex          填充行座標
     * @param colWidth          列寬
     * @param rowHeight         行高
     * @param sheetIndex        sheet下標
     * @param excelConfigExt    擴展配置
     */
    public ExcelRowSignData(ExportExcelCustom exportExcelCustom, List<AbstractExcelData> rowData, Integer colIndex, Integer rowIndex, Integer colWidth, Integer rowHeight, Integer sheetIndex, ExcelConfigExt excelConfigExt) {
        super(exportExcelCustom, rowData, colIndex, rowIndex, colWidth, rowHeight, sheetIndex, excelConfigExt);
    }


    @Override
    public void fillData() {
        this.getExportExcelCustom().fillRowSignData(this);
    }
}
/**
 * @Author: Vachel Wang
 * @Date: 2017/5/2
 * @Time: 下午8:24
 * @Version: V1.0
 * @Description: 單列內容,內容暫時未做限制,僅支持
 */
public class ExcelTextData extends AbstractExcelData {
    /**
     * @param exportExcelCustom 處理excel對象
     * @param data              數據
     * @param colIndex          列座標
     * @param rowIndex          行座標
     * @param colWidth          列寬
     * @param rowHeight         行高
     * @param sheetIndex        sheet下標
     * @param excelConfigExt    擴展配置
     */
    public ExcelTextData(ExportExcelCustom exportExcelCustom, Object data, Integer colIndex, Integer rowIndex, Integer colWidth, Integer rowHeight, Integer sheetIndex, ExcelConfigExt excelConfigExt) {
        super(exportExcelCustom, data, colIndex, rowIndex, colWidth, rowHeight, sheetIndex, excelConfigExt);
    }

    @Override
    public void fillData() {
        this.getExportExcelCustom().fillTextData(this);
    }

}

 

/**
 * @Author: Vachel Wang
 * @Date: 2017/5/2
 * @Time: 下午8:28
 * @Version: V1.0
 * @Description: 標題內容
 */
public class ExcelTitleData extends AbstractExcelData {
    /**
     * @param exportExcelCustom 處理excel對象
     * @param dataArr           數據
     * @param colIndex          列座標
     * @param rowIndex          行座標
     * @param colWidth          列寬
     * @param rowHeight         行高
     * @param sheetIndex        sheetIndex
     * @param excelConfigExt    擴展配置
     */
    public ExcelTitleData(ExportExcelCustom exportExcelCustom, String[] dataArr, Integer colIndex, Integer rowIndex, Integer colWidth, Integer rowHeight, Integer sheetIndex, ExcelConfigExt excelConfigExt) {
        super(exportExcelCustom, dataArr, colIndex, rowIndex, colWidth, rowHeight, sheetIndex, excelConfigExt);
    }

    @Override
    public void fillData() {
        this.getExportExcelCustom().fillExcelTitleData(this);
    }
}

 

/**
 * @Author: Vachel Wang
 * @Date: 2017/5/2
 * @Time: 下午8:28
 * @Version: V1.0
 * @Description: 重構自定義導出
 * 1.具體導出規則由子類實現,方便後期維護和添加導出其它格式,符合開閉原則
 * 2.重構代碼結構去掉冗餘代碼,優化導出方式
 */
public interface ExportExcelCustom {
    /**
     * 模板替換字符串
     */
    String REPLACE_CHAR = "%s";
    /**
     * 高度換算率=1px
     */
    double HEIGIT_TIMES = 15.625;
    /**
     * 寬度度換算率=1px
     */
    double WIDTH_TIMES = 35.7;

    /**
     * 導出
     *
     * @param fileName 文件名
     * @param response response
     */
    void export(String fileName, HttpServletResponse response);

    /**
     * 填充文本數據
     *
     * @param textData 數據
     */
    void fillTextData(ExcelTextData textData);

    /**
     * 填充圖片數據
     *
     * @param pictureData 數據
     */
    void fillPictureData(ExcelPictureData pictureData);

    /**
     * 填充單行數據
     *
     * @param rowSignData 數據
     */
    void fillRowSignData(ExcelRowSignData rowSignData);

    /**
     * 填充多行數據
     *
     * @param rowMultiData 數據
     */
    void fillRowMultiData(ExcelRowMultiData rowMultiData);

    /**
     * 填充標題數據
     *
     * @param titleData 數據
     */
    void fillExcelTitleData(ExcelTitleData titleData);

    /**
     * 獲取Workbook對象
     *
     * @return Workbook
     */
    Workbook getWorkbook();
}
/**
 * 通過自定義模板導出excel 僅支持導出xlsx格式
 *
 * @author Vachel.Wang
 * @version V1.1
 * @date 2016年7月4日 下午1:52:23
 */
public class ExportExcelCustomXlsx implements ExportExcelCustom {

	private XSSFWorkbook workbook = null;
	private static final Logger LOG = LoggerFactory.getLogger(ExportExcelCustomXlsx.class);
	private Map<String,XSSFFont> fontMap = null ;
	private Map<String,XSSFCellStyle> styleMap = null ;
	/**
	 * 構造
	 *
	 * @param templatePath
	 *            模板路徑,可填項
	 * @throws IOException
	 * @throws InvalidFormatException
	 */
	public ExportExcelCustomXlsx(String templatePath) throws IOException, InvalidFormatException {
		if (templatePath == null) {
			workbook = new XSSFWorkbook();
		} else {
			File file = new File(templatePath);
			if (!file.exists())
				throw new IOException("文件不存在:" + templatePath);
			workbook = (XSSFWorkbook) WorkbookFactory.create(file);
		}
		styleMap = ExcelStyleEnum.setWorkbookStyle(workbook);
		fontMap = ExcelFontEnum.setWorkbookFont(workbook);
	}

	/**
	 * 導出
	 *
	 * @param fileName
	 * @param response
	 */
	@Override
	public void export(String fileName, HttpServletResponse response) {
		OutputStream outputStream = null;
		try {
			response.reset();
			response.setContentType("application/octet-stream; charset=utf-8");
			response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
			outputStream = response.getOutputStream();
			workbook.write(outputStream);
		} catch (IOException e) {
			LOG.info(e.getMessage(), e);
			throw new GenericException("導出excel異常");
		} finally {
			try {
				if (null != outputStream) {
					outputStream.flush();
					outputStream.close();
				}
			} catch (IOException e) {
				LOG.info(e.getMessage(), e);
			}
		}
	}

	/**
	 * 根據下標獲取sheet,如果不存在則創建
	 *
	 * @param sheetIndex
	 * @param newSheetName
	 * @return
	 */
	private XSSFSheet getSheet(Integer sheetIndex, String newSheetName) {
		XSSFSheet sheet;
		if (workbook.getNumberOfSheets() < (sheetIndex + 1)) {
			if (newSheetName == null)
				newSheetName = "newsheet" + (sheetIndex + 1);
			sheet = workbook.createSheet(newSheetName);
		} else {
			sheet = workbook.getSheetAt(sheetIndex);
		}
		return sheet;
	}

	/**
	 * 根據行下標獲取Row不存在則創建
	 *
	 * @param sheet
	 * @param rowIndex
	 * @return
	 */
	private XSSFRow getRow(XSSFSheet sheet, Integer rowIndex) {
		XSSFRow row = sheet.getRow(rowIndex);
		if (row == null)
			row = sheet.createRow(rowIndex);
		return row;
	}

	/**
	 * 插入一行
	 *
	 * @param sheet
	 * @param rowIndex
	 * @return
	 */
	private XSSFRow createRow(XSSFSheet sheet, Integer rowIndex) {
		XSSFRow row = null;
		if (sheet.getRow(rowIndex) != null) {
			int lastRowNo = sheet.getLastRowNum();
			sheet.shiftRows(rowIndex, lastRowNo, 1);
		}
		row = sheet.createRow(rowIndex);
		return row;
	}

	/**
	 * 根據下標獲取cell不存在則創建
	 *
	 * @param row
	 * @param colIndex
	 * @return
	 */
	private XSSFCell getCell(XSSFRow row, Integer colIndex) {
		XSSFCell cell = row.getCell(colIndex);
		if (cell == null)
			cell = row.createCell(colIndex);
		return cell;
	}

	/**
	 * 設置單元格寬高度
	 *
	 * @param abstractExcelData
	 * @param sheet
	 * @param row
	 */
	private void setWidthAndHeight(AbstractExcelData abstractExcelData, XSSFSheet sheet, XSSFRow row) {
		if (abstractExcelData.getRowHeight() != null)
			row.setHeight((short) (HEIGIT_TIMES * abstractExcelData.getRowHeight()));
		if (abstractExcelData.getColWidth() != null)
			sheet.setColumnWidth(abstractExcelData.getColIndex(), (short) (WIDTH_TIMES * abstractExcelData.getColWidth()));
	}

	@Override
	public void fillTextData(ExcelTextData textData) {
		// 獲取sheet
		XSSFSheet sheet = getSheet(textData.getSheetIndex(), textData.getExcelConfigExt().getNewSheetName());
		// 獲取row
		XSSFRow row = getRow(sheet, textData.getRowIndex());
		// 獲取cell
		XSSFCell cell = getCell(row, textData.getColIndex());
		// 設置尺寸
		setWidthAndHeight(textData, sheet, row);
		// 填充數據
		fillCellContent(cell, textData.getData(), textData.getExcelConfigExt());
	}

	@Override
	public void fillPictureData(ExcelPictureData pictureData) {
		// 獲取sheet
		XSSFSheet sheet = getSheet(pictureData.getSheetIndex(), pictureData.getExcelConfigExt().getNewSheetName());
		// 獲取row
		XSSFRow row = getRow(sheet, pictureData.getStartRowIndex());
		// 獲取cell
		XSSFCell cell = getCell(row, pictureData.getStartColIndex());
		// 設置尺寸
		setWidthAndHeight(pictureData, sheet, row);
		// 填充數據
		fillCellPicture(sheet, pictureData);
	}

	@Override
	public void fillRowSignData(ExcelRowSignData rowSignData) {
		List<AbstractExcelData> rowData = (List<AbstractExcelData>) rowSignData.getData();
		XSSFSheet sheet = getSheet(rowSignData.getSheetIndex(), rowSignData.getExcelConfigExt().getNewSheetName());
		createRow(sheet, rowSignData.getRowIndex());
		for (int j = 0; j < rowData.size(); j++) {
			AbstractExcelData abstractExcelData = rowData.get(j);

			// 圖片
			if (abstractExcelData instanceof ExcelPictureData) {
				ExcelPictureData pictureData = (ExcelPictureData) abstractExcelData;
				pictureData.setStartColIndex(rowSignData.getColIndex() + j);
				pictureData.setEndColIndex(rowSignData.getColIndex() + j + 1);
				pictureData.setStartRowIndex(rowSignData.getRowIndex());
				pictureData.setEndRowIndex(rowSignData.getRowIndex() + 1);
				pictureData.setSheetIndex(rowSignData.getSheetIndex());

			} else if (abstractExcelData instanceof ExcelTextData) { // 文本
				ExcelTextData excelTextData = (ExcelTextData) abstractExcelData;
				excelTextData.setColIndex(rowSignData.getColIndex() + j);
				excelTextData.setRowIndex(rowSignData.getRowIndex());
				excelTextData.setSheetIndex(rowSignData.getSheetIndex());
			}
			abstractExcelData.fillData();
		}
	}

	@Override
	public void fillRowMultiData(ExcelRowMultiData rowMultiData) {
		List<ArrayList<AbstractExcelData>> multiData = (List<ArrayList<AbstractExcelData>>) rowMultiData.getData();
		// 行
		for (int k = 0; k < multiData.size(); k++) {
			ArrayList<AbstractExcelData> columnDataList = multiData.get(k);
			ExcelRowSignData signData = new ExcelRowSignData(rowMultiData.getExportExcelCustom(), columnDataList,
					rowMultiData.getColIndex(), rowMultiData.getRowIndex() + k, rowMultiData.getColWidth(),
					rowMultiData.getRowHeight(), rowMultiData.getSheetIndex(), rowMultiData.getExcelConfigExt());
			signData.fillData();
		}
	}

	@Override
	public void fillExcelTitleData(ExcelTitleData titleData) {
		if (titleData.getExcelConfigExt().getFont() == null) {
			/* 默認標題字體 */
			XSSFFont titleFont = fontMap.get(ExcelFontEnum.TITLE_SIZE16_BLOLD.toString());
			titleData.getExcelConfigExt().setFont(titleFont);
		}
		if (titleData.getExcelConfigExt().getCellStyle() == null) {
			/* 默認標題樣式 */
			XSSFCellStyle titleStyle = styleMap.get(ExcelStyleEnum.STYLE_ALIGN_CENTER_VERTICAL_CENTER_BORDER.toString());
			titleData.getExcelConfigExt().setCellStyle(titleStyle);
		}
		// 獲取sheet
		XSSFSheet sheet = getSheet(titleData.getSheetIndex(), titleData.getExcelConfigExt().getNewSheetName());
		// 獲取row
		XSSFRow row = getRow(sheet, titleData.getRowIndex());

		String[] titleDataArr = (String[]) titleData.getData();
		for (int i = 0; i < titleDataArr.length; i++) {
			XSSFCell cell = getCell(row, titleData.getColIndex() + i);
			cell.setCellValue(titleDataArr[i]);
			cell.setCellStyle(titleData.getExcelConfigExt().getCellStyle());
		}
	}

	/**
	 * 填充內容
	 *
	 * @param cell
	 * @param data
	 */
	private void fillCellContent(XSSFCell cell, Object data, ExcelConfigExt configExt) {
		if (cell == null)
			return;
		if (data == null) {
			String cellData = getStringCellValue(cell);
			cell.setCellValue(cellData.replaceAll(REPLACE_CHAR, ""));
			return;
		}
		String cellData = getStringCellValue(cell);
		// 字符串
		if (data instanceof String) {
			String strData = data.toString();
			if (cellData.indexOf(REPLACE_CHAR) != -1) {
				cellData = String.format(cellData, strData.split(";"));
			} else {
				cellData += strData;
			}
			cell.setCellValue(cellData);
		}
		// 整數
		else if (data instanceof Integer) {
			Integer integerData = (Integer) data;
			if (cellData.equals("")) {
				cell.setCellValue(integerData);
			} else if (cellData.indexOf(REPLACE_CHAR) != -1) {
				cellData = cellData.replaceAll(REPLACE_CHAR, String.valueOf(integerData));
				cell.setCellValue(cellData);
			} else {
				cell.setCellValue(integerData);
			}
		}
		// 長整數
		else if (data instanceof Long) {
			Long longData = (Long) data;
			if (cellData.equals("")) {
				cell.setCellValue(longData);
			} else if (cellData.indexOf(REPLACE_CHAR) != -1) {
				cellData = cellData.replaceAll(REPLACE_CHAR, String.valueOf(longData));
				cell.setCellValue(cellData);
			} else {
				cell.setCellValue(longData);
			}
		}
		// 小數
		else if (data instanceof Double) {
			Double doubleData = (Double) data;
			if (cellData.equals("")) {
				cell.setCellValue(doubleData);
			} else if (cellData.indexOf(REPLACE_CHAR) != -1) {
				cellData = cellData.replaceAll(REPLACE_CHAR, String.valueOf(doubleData));
				cell.setCellValue(cellData);
			} else {
				cell.setCellValue(doubleData);
			}
		}
		// 時間
		else if (data instanceof Date) {
			Date dateData = (Date) data;
			if (cellData.equals("")) {
				cell.setCellValue(dateData);
			} else if (cellData.indexOf(REPLACE_CHAR) != -1) {
				cellData = cellData.replace(REPLACE_CHAR, DateUtil.formatYYYYMMDDHHMMSS(dateData));
				cell.setCellValue(cellData);
			} else {
				cell.setCellValue(DateUtil.formatYYYYMMDDHHMMSS(dateData));
			}
		}
		// 數組
		else if (data instanceof String[]) {
			String[] strArr = (String[]) data;
			String str = "";

			if (cellData.equals("")) {
				for (String s : strArr) {
					str += "," + s;
				}
				if (str.length() > 0)
					str = str.substring(1);
			} else if (cellData.indexOf(REPLACE_CHAR) != -1) {
				str = String.format(cellData, strArr);
			}
			cell.setCellValue(str);
		}
		// 其它
		else {
			cell.setCellValue(data + "");
		}
		cell.setCellStyle(configExt.getCellStyle());
	}

	/**
	 * 填充圖片
	 *
	 * @param sheet
	 * @param pictureData
	 */
	private void fillCellPicture(XSSFSheet sheet, ExcelPictureData pictureData) {
		if (pictureData == null || pictureData.getData() == null)
			return;
		byte bytes[] = (byte[]) pictureData.getData();
		int pictureIdx = workbook.addPicture(bytes, XSSFWorkbook.PICTURE_TYPE_JPEG);
		Drawing drawing = sheet.createDrawingPatriarch();
		XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 255, 255, pictureData.getStartColIndex(),
				pictureData.getStartRowIndex(), pictureData.getEndColIndex(), pictureData.getEndRowIndex());
		drawing.createPicture(anchor, pictureIdx);
	}

	@Override
	public XSSFWorkbook getWorkbook() {
		return workbook;
	}

}

 

/**
 * Excel 樣式枚舉
 * @author Vachel Wang
 */
public enum ExcelFontEnum {

    TITLE_SIZE16_BLOLD((short)16,null,"Courier New",true,false,false,FontUnderline.NONE),
    CONTENT_SIZE12((short)12,null,"Courier New",false,false,false,FontUnderline.NONE),
    CONTENT_SIZE12_BLOLD((short)12,null,"Courier New",true,false,false,FontUnderline.NONE),
    CONTENT_SIZE12_BLOLD_UNDERLINE((short)12,null,"Courier New",true,false,false,FontUnderline.SINGLE),
    ;

    ExcelFontEnum(Short fontSize, XSSFColor fontColor , String fontName, Boolean bold, Boolean italic, Boolean strikeout,FontUnderline fontUnderline) {
        if(fontSize!=null)
            this.fontSize = fontSize;
        if(fontColor!=null)
            this.fontColor = fontColor;
        if(fontName!=null)
            this.fontName = fontName;
        if(bold!=null)
            this.bold = bold;
        if(italic!=null)
            this.italic = italic;
        if(strikeout!=null)
            this.strikeout = strikeout;
        if(fontUnderline!=null)
            this.fontUnderline = fontUnderline;
    }

    // 字體大小
    private Short fontSize = 12 ;
    // 字體顏色
    private XSSFColor fontColor = new XSSFColor(new Color(0,0,0,1)) ;
    // 字體名
    private String fontName = "Courier New" ;
    // 是否加粗
    private Boolean bold = false ;
    // 斜體
    private Boolean italic = false ;
    // 刪除線
    private Boolean strikeout = false ;
    // 下劃樣式
    private FontUnderline fontUnderline = FontUnderline.NONE ;

    public static Map<String,XSSFFont> setWorkbookFont(XSSFWorkbook workbook){
        Map<String,XSSFFont> fontMap = new HashMap<>() ;
        for(ExcelFontEnum fontEnum : ExcelFontEnum.values()){
            XSSFFont font = workbook.createFont() ;
            font.setFontHeightInPoints(fontEnum.fontSize);
            font.setColor(fontEnum.fontColor);
            font.setFontName(fontEnum.fontName);
            font.setBold(fontEnum.bold);
            font.setItalic(fontEnum.italic);
            font.setStrikeout(fontEnum.strikeout);
            font.setUnderline(fontEnum.fontUnderline);
            fontMap.put(fontEnum.toString(),font) ;
        }
        return fontMap ;
    }

}

 

/**
 * Excel 樣式枚舉
 * @author Vachel Wang
 */
public enum ExcelStyleEnum {

    STYLE_ALIGN_CENTER_VERTICAL_CENTER_BORDER(CellStyle.ALIGN_CENTER,CellStyle.VERTICAL_CENTER,new XSSFColor(new java.awt.Color(220,220,220)),CellStyle.SOLID_FOREGROUND,new XSSFColor(new java.awt.Color(0,0,0)), BorderStyle.THIN),
    STYLE_ALIGN_LEFT_VERTICAL_CENTER(CellStyle.ALIGN_LEFT,CellStyle.VERTICAL_CENTER,new XSSFColor(new java.awt.Color(220,220,220)),CellStyle.SOLID_FOREGROUND,null,null),
    ;

    ExcelStyleEnum(Short alignment, Short verticalAlignment, XSSFColor fillForegroundColor, Short fillPattern,XSSFColor borderColor,BorderStyle borderStyle) {
        if(alignment!=null)
            this.alignment = alignment;
        if(verticalAlignment!=null)
            this.verticalAlignment = verticalAlignment;
        if(fillForegroundColor!=null)
            this.fillForegroundColor = fillForegroundColor;
        if(fillPattern!=null)
            this.fillPattern = fillPattern;
        if(borderColor!=null)
            this.borderColor = borderColor;
        if(borderStyle!=null)
            this.borderStyle = borderStyle;
    }
    // 水平對齊方式
    private Short alignment = CellStyle.ALIGN_LEFT ;
    // 垂直對齊方式
    private Short verticalAlignment = CellStyle.VERTICAL_BOTTOM ;
    // 前景色
    private XSSFColor fillForegroundColor = null ;
    // 前景色填充模式
    private Short fillPattern = CellStyle.SOLID_FOREGROUND;
    // 邊框顏色
    private XSSFColor borderColor = null ;
    // 邊框樣式
    private BorderStyle borderStyle = BorderStyle.NONE ;

    public static Map<String,XSSFCellStyle> setWorkbookStyle(XSSFWorkbook workbook){
        Map<String,XSSFCellStyle> styleMap = new HashMap<>() ;
        for(ExcelStyleEnum styleEnum : ExcelStyleEnum.values()){
            XSSFCellStyle cellStyle = workbook.createCellStyle();
            cellStyle.setAlignment(styleEnum.alignment);
            cellStyle.setVerticalAlignment(styleEnum.verticalAlignment);
            cellStyle.setFillForegroundColor(styleEnum.fillForegroundColor);
            cellStyle.setFillPattern(styleEnum.fillPattern);
            if(styleEnum.borderColor!=null){
                cellStyle.setBottomBorderColor(styleEnum.borderColor);
                cellStyle.setTopBorderColor(styleEnum.borderColor);
                cellStyle.setLeftBorderColor(styleEnum.borderColor);
                cellStyle.setRightBorderColor(styleEnum.borderColor);
            }
            if(styleEnum.borderStyle!=null){
                cellStyle.setBorderBottom(styleEnum.borderStyle);
                cellStyle.setBorderTop(styleEnum.borderStyle);
                cellStyle.setBorderRight(styleEnum.borderStyle);
                cellStyle.setBorderLeft(styleEnum.borderStyle);
            }
            styleMap.put(styleEnum.toString(),cellStyle);
        }
        return styleMap;
    }

}

 

 

 

 

 

 

 

 

 

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