package com.ruoyi.report.service.impl;

import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
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.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.DefaultIndexedColorMap;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;

public class AbstractExcelExp {

	
	
	protected void writeToOut(SXSSFWorkbook wb,OutputStream out) {
		try {
			wb.write(out);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(wb);
//			IOUtils.closeQuietly(out);
		}
	}

	/**
	 * 创建表格样式
	 * 
	 * @param wb 工作薄对象
	 * @return 样式列表
	 */
	protected Map<String, XSSFCellStyle > createStyles(Workbook wb) {
		// 写入各条记录,每条记录对应excel表中的一行
		Map<String, XSSFCellStyle> styles = new HashMap<String, XSSFCellStyle>();
		XSSFCellStyle  style = (XSSFCellStyle )wb.createCellStyle();
		style.setAlignment(HorizontalAlignment.CENTER);
		style.setVerticalAlignment(VerticalAlignment.CENTER);
		Font titleFont = wb.createFont();
		titleFont.setFontName("Arial");
		titleFont.setFontHeightInPoints((short) 16);
		titleFont.setBold(true);
		style.setFont(titleFont);
		styles.put("title", style);

		style = (XSSFCellStyle )wb.createCellStyle();
		style.setAlignment(HorizontalAlignment.CENTER);
		style.setVerticalAlignment(VerticalAlignment.CENTER);
		style.setBorderRight(BorderStyle.THIN);
		style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
		style.setBorderLeft(BorderStyle.THIN);
		style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
		style.setBorderTop(BorderStyle.THIN);
		style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
		style.setBorderBottom(BorderStyle.THIN);
		style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
		Font dataFont = wb.createFont();
		dataFont.setFontName("Arial");
		dataFont.setFontHeightInPoints((short) 10);
		style.setFont(dataFont);
		styles.put("data", style);
		
		
		XSSFCellStyle dataStyle2 = (XSSFCellStyle )wb.createCellStyle();
		dataStyle2.cloneStyleFrom(styles.get("data"));
		dataStyle2.setWrapText(true); 
		styles.put("data2", dataStyle2);
		

		style = (XSSFCellStyle )wb.createCellStyle();
		style.cloneStyleFrom(styles.get("data"));
		style.setAlignment(HorizontalAlignment.CENTER);
		style.setVerticalAlignment(VerticalAlignment.CENTER);
		XSSFColor bgColor = new XSSFColor(new java.awt.Color(42,142,237), new DefaultIndexedColorMap());
		style.setFillForegroundColor(bgColor);
		
		style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		style.setBottomBorderColor(IndexedColors.WHITE.getIndex());
		style.setTopBorderColor(IndexedColors.WHITE.getIndex());
		style.setLeftBorderColor(IndexedColors.WHITE.getIndex());
		style.setRightBorderColor(IndexedColors.WHITE.getIndex());
		Font headerFont = wb.createFont();
		headerFont.setFontName("Arial");
		headerFont.setFontHeightInPoints((short) 11);
		headerFont.setBold(true);
		headerFont.setColor(IndexedColors.WHITE.getIndex());
		style.setFont(headerFont);
		styles.put("header", style);

		
		XSSFCellStyle cellStyle2 = (XSSFCellStyle )wb.createCellStyle();
		cellStyle2.cloneStyleFrom(styles.get("header"));
		cellStyle2.setWrapText(true); 
		styles.put("header2", cellStyle2);
//		style = (XSSFCellStyle )wb.createCellStyle();
//		style.setAlignment(HorizontalAlignment.CENTER);
//		style.setVerticalAlignment(VerticalAlignment.CENTER);
//		Font totalFont = wb.createFont();
//		totalFont.setFontName("Arial");
//		totalFont.setFontHeightInPoints((short) 10);
//		style.setFont(totalFont);
//		styles.put("total", style);

//		style = (XSSFCellStyle )wb.createCellStyle();
//		style.cloneStyleFrom(styles.get("data"));
//		style.setAlignment(HorizontalAlignment.LEFT);
//		styles.put("data1", style);
//
//		style = (XSSFCellStyle )wb.createCellStyle();
//		style.cloneStyleFrom(styles.get("data"));
//		style.setAlignment(HorizontalAlignment.CENTER);
//		styles.put("data2", style);
//
//		style = (XSSFCellStyle )wb.createCellStyle();
//		style.cloneStyleFrom(styles.get("data"));
//		style.setAlignment(HorizontalAlignment.RIGHT);
//		styles.put("data3", style);

		return styles;
	}
	
	
	protected static void setRegionStyle(SXSSFSheet sheet, CellRangeAddress region, XSSFCellStyle cs) {
	    for (int i = region.getFirstRow(); i <= region.getLastRow(); i++) {
	    	SXSSFRow row = sheet.getRow(i);
	         if (null == row) row = sheet.createRow(i);
	         for (int j = region.getFirstColumn(); j <= region.getLastColumn(); j++) {
	        	 SXSSFCell cell = row.getCell(j);
	              if (null == cell) cell = row.createCell(j);
	              cell.setCellStyle(cs);
	         }
	     }
	}
	protected static void autoColumnWidthForChineseChar(Sheet sheet, int startColumnNum, int size,int minWidth) {   
		autoColumnWidthForChineseChar(sheet,startColumnNum,size,minWidth,0);
	}
	
	protected static void autoColumnWidthForChineseChar(Sheet sheet, int startColumnNum, int size,int minWidth,int maxWidth) {    
	    for (int columnNum = 0; columnNum < size; columnNum++) {
	    	/** 调整每一列宽度 */ 
			sheet.autoSizeColumn(columnNum);
	        /** 获取列宽 */
	        final int columnWidth = sheet.getColumnWidth(columnNum);
	        if(columnNum >= 256*256 ){
	        	/** 列宽已经超过最大列宽则放弃当前列遍历 */
	        	continue;
	        }
	        /** 新的列宽 */
	        int newWidth = columnWidth;
	        /** 遍历所有的行,查找有汉字的列计算新的最大列宽 */
	        for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) {
	            Row currentRow;
	            if (sheet.getRow(rowNum) == null) {
	                continue;
	            } else {
	                currentRow = sheet.getRow(rowNum);
	            }
	            if (currentRow.getCell(columnNum) != null) {
	                Cell currentCell = currentRow.getCell(columnNum);
	                if (currentCell.getCellType() == CellType.STRING) {
	                	String value = currentCell.getStringCellValue();
	                	/** 计算字符串中中文字符的数量 */
	                    int count = chineseCharCountOf(value);
	                    /**在该列字符长度的基础上加上汉字个数计算列宽 */
	                    int length = value.length()*256+count*256*2;
	                	/** 使用字符串的字节长度计算列宽 */
//	                    int length = value.getBytes().length*256;
	                    if (newWidth < length && length < 256*256) {
	                    	newWidth = length;
	                    }
	                }
	            }
	        }
	        if(newWidth<minWidth) {
	        	newWidth=minWidth;
	        }
	        if(maxWidth>0 && newWidth>maxWidth) {
	        	newWidth=maxWidth;
	        }
	        if(newWidth != columnWidth){
	        	//设置列宽
//	        	System.out.println("设置列宽:"+newWidth);
	        	sheet.setColumnWidth(columnNum, newWidth);
	        }
	    }
	}
	/**
	 * 计算字符串中中文字符的数量
	 * 参见 <a hrft="https://www.cnblogs.com/straybirds/p/6392306.html">《汉字unicode编码范围》</a>
	 * @param input
	 * @return
	 */
	private static int chineseCharCountOf(String input){
		int count = 0;//汉字数量
		if(null != input){
			String regEx = "[\\u4e00-\\u9fa5]";
			Pattern p = Pattern.compile(regEx);
			Matcher m = p.matcher(input);
			int len = m.groupCount();
			//获取汉字个数
			while (m.find()) {
				for (int i = 0; i <= len; i++) {
					count = count + 1;
				}
			}
		}
		return count;
	}
	
	
	protected Cell createCell(Row row,int column,Object val,XSSFCellStyle style) {
		Cell cell = row.createCell(column);
		cell.setCellStyle(style);
		if(val!=null) {
			if(val instanceof Integer) {
				cell.setCellValue((Integer)val);
			}else if(val instanceof Long) {
				cell.setCellValue((Long)val);
			}else {
				cell.setCellValue(val.toString());
			}
			
		}else {
			cell.setCellValue("");
		}
		
		return cell;
	}
}
