/**
 * 系统数据导出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 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 ExportExcelUtil {

	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);
			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);
			//数字格式
			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(rowList.get(n) != null){
						cell.setCellStyle(cellStyle1);
						cell.setCellValue((String) rowList.get(n).toString());
					}else{
						cell.setCellValue("");
					}
				}
			}
			//设置自动列宽
			for (int j = 0; j < rows; j++) {
				sheet.autoSizeColumn(j);
				int width = sheet.getColumnWidth(j)*2;
				if(width < 3000){
					sheet.setColumnWidth(j,sheet.getColumnWidth(j)*17/10);
				}
			}
			//冻结表头
			sheet.createFreezePane( 0, 1, 0, 1 );
		}
		return workBook;
	}

	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;
	}
}
