/**
 * 系统数据导出Excel 生成器
 * @version 1.0
 */
package com.emr.util;
import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.util.CellRangeAddressList;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


public class ExportBloodExcelUtil {

	private final int SPLIT_COUNT = 1000;

	private static List<String> fieldName = null;

	private static List<List<String>> fieldData = null;

	private String fileName;

	private HSSFWorkbook workBook = null;
	public List<String> getFieldName(String tableThNames){
		String[] names = tableThNames.split(",");
		List<String> fieldName = new ArrayList<>();
		if (names != null) {
			for (int i = 0; i < names.length; i++) {
				if (StringUtils.isNoneBlank(names[i])) {
					fieldName.add(names[i]);
				}
			}
		}
		return fieldName;
	}

	public List<List<String>> getFieldData(String fieldCns, Collection list){
		List<List<String>> fieldData = new ArrayList<List<String>>();
		String[] fieldList = fieldCns.split(",");
		Object[] objects = list.toArray();
		for (Object object : objects) {
			List<String> data = new ArrayList<String>();
			for (String english : fieldList) {
				String field = fieldToProperty(english);
				String value = getFieldValueByFieldName(field,object);
				data.add(value);
			}
			fieldData.add(data);
		}
		return fieldData;
	}
	public void expordExcel(String tableThNames,String fieldCns,Collection list,String fileName,HttpServletResponse response) throws Exception {
		this.fieldName = getFieldName(tableThNames);
		this.fieldData = getFieldData(fieldCns,list);
		this.fileName = fileName;
		OutputStream os = response.getOutputStream();
		response.reset();
		response.setContentType("application/OCTET-STREAM;charset=gbk");
		response.setHeader("pragma", "no-cache");
		fileName = new String(fileName.getBytes("utf-8"), "iso-8859-1");
		response.setHeader("Content-disposition", "attachment;filename=\"" + fileName + "\"");
		response.setBufferSize(1024);
		workBook = createWorkbook();
		workBook.write(os);
		os.close();
	}
	public HSSFWorkbook createWorkbook() {
		workBook = new HSSFWorkbook();
		int rows = fieldData.size();
		int sheetNum = 0;

		if (rows % SPLIT_COUNT == 0) {
			sheetNum = rows / SPLIT_COUNT;
		} else {
			sheetNum = rows / SPLIT_COUNT + 1;
		}
		if(sheetNum == 0){
			sheetNum = 1;
		}
		for (int i = 1; i <= sheetNum; i++) {
			HSSFSheet sheet = workBook.createSheet("Sheet " + i);
			//第三列限制数字1-365
			HSSFDataValidation dateVa = setValidate(2,2,365);
			//限制下拉框
			String[] strs = {"个人申请","科研"};
			HSSFDataValidation boxVa = setBoxs(3,3,strs);

			// 设定规则
			// sheet.addValidationData(validate);
			// sheet.addValidationData(validateData);
			sheet.addValidationData(dateVa);
			sheet.addValidationData(boxVa);

			HSSFRow headRow = sheet.createRow((short) 0);

			HSSFCellStyle cellStyle = workBook.createCellStyle();
			cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
			cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

			HSSFFont font = workBook.createFont();
			font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
			font.setColor(HSSFColor.RED.index);
			font.setFontHeightInPoints((short) 12);
			cellStyle.setFont(font);

			for (int j = 0; j < fieldName.size(); j++) {
				HSSFCell cell = headRow.createCell( j);
				sheet.setColumnWidth(j, 6000);
				cell.setCellType(HSSFCell.CELL_TYPE_STRING);
				if(fieldName.get(j) != null){
					cell.setCellStyle(cellStyle);
					cell.setCellValue((String) fieldName.get(j));
				}else{
					cell.setCellValue("-");
				}
			}
			HSSFCellStyle cellStyle1 = workBook.createCellStyle();
			cellStyle1.setAlignment(HSSFCellStyle.ALIGN_CENTER);
			cellStyle1.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
			cellStyle1.setLocked(false);//设置未锁定
			//锁定样式
			HSSFCellStyle lockstyle = workBook.createCellStyle();
			lockstyle.setLocked(true);//设置锁定
			lockstyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
			lockstyle.setFillForegroundColor(IndexedColors.RED.getIndex());//设置上锁的单元格背景色
			lockstyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
			lockstyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

			//数字格式
			for (int k = 0; k < (rows < SPLIT_COUNT ? rows : SPLIT_COUNT); k++) {
				if (((i - 1) * SPLIT_COUNT + k) >= rows)
					break;
				HSSFRow row = sheet.createRow((short) (k + 1));
				ArrayList<String> rowList = (ArrayList<String>) fieldData.get((i - 1) * SPLIT_COUNT + k);
				for (int n = 0; n < rowList.size(); n++) {
					HSSFCell cell = row.createCell( n);
					if(n == 0 || n == 1){
						cell.setCellStyle(lockstyle);
					}else{
						cell.setCellStyle(cellStyle1);
					}
					if(rowList.get(n) != null){
						cell.setCellValue((String) rowList.get(n).toString());
					}else{
						cell.setCellValue("");
					}
				}
			}
			//设置自动列宽
			for (int j = 0; j < rows; j++) {
				sheet.autoSizeColumn(j);
				sheet.setColumnWidth(j,sheet.getColumnWidth(j)*17/10);
			}
			//冻结表头
			sheet.createFreezePane( 0, 1, 0, 1 );
			sheet.protectSheet("123456");
		}
		return workBook;
	}

	// 数字大小控制：设置单元格只能在1-365之间,firstCol:起始列，lastCol结束列，maxNum最大数字
	public static HSSFDataValidation setValidate(int firstCol, int lastCol,int maxNum) {
		// 创建一个规则：1-365的数字
		DVConstraint constraint = DVConstraint.createNumericConstraint(DVConstraint.ValidationType.INTEGER,
				DVConstraint.OperatorType.BETWEEN, "1", String.valueOf(maxNum));
		// 设定在哪个单元格生效
		CellRangeAddressList regions = new CellRangeAddressList(1, 1000, firstCol, lastCol);
		// 创建规则对象
		HSSFDataValidation ret = new HSSFDataValidation(regions, constraint);
		ret.createPromptBox("输入提示", "请输入数字1到"+maxNum);
		return ret;
	}
	// 下拉框限制firstCol:起始列，lastCol结束列，strs 限制下拉框数组
	public static HSSFDataValidation setBoxs(int firstCol,int lastCol,String [] strs) {
		CellRangeAddressList addressList = new CellRangeAddressList(1, 1000, firstCol, lastCol);
		final String[] DATA_LIST = strs;
		DVConstraint dvConstraint = DVConstraint.createExplicitListConstraint(DATA_LIST);

		HSSFDataValidation dataValidation = new HSSFDataValidation(addressList, dvConstraint);
		dataValidation.setSuppressDropDownArrow(false);
		dataValidation.createPromptBox("输入提示", "请从下拉列表中选择");
		dataValidation.setShowPromptBox(true);

		return dataValidation;
	}

	public static String fieldToProperty(String field) {
		if (null == field) {
			return "";
		}
		char[] chars = field.toCharArray();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < chars.length; i++) {
			char c = chars[i];
			if (c == '_') {
				int j = i + 1;
				if (j < chars.length) {
					sb.append(StringUtils.upperCase(CharUtils.toString(chars[j])));
					i++;
				}
			} else {
				sb.append(c);
			}
		}
		return sb.toString();
	}

	public static String getFieldValueByFieldName(String fieldName, Object object) {
		try {
			Class<?> clazz = object.getClass();
			for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
				Field[] field = clazz.getDeclaredFields();
				for (Field f : field) {
					if(fieldName.equals(f.getName())){
						f.setAccessible(true);
						if(f.get(object) != null){
							return f.get(object).toString();
						}else{
							return "";
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return null;
	}
}
