package market.Qms.common;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFPicture;
import org.apache.poi.hssf.usermodel.HSSFPictureData;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFShape;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;

public class MergeHSSFSheet {
	Set<String> mergedRegions = new TreeSet<String>();

	// 日期格式
	private String dateFormat = "yyyy/mm/dd hh:mm";

	/**
	 * 拼接两个sheet页到一个sheet页上
	 * 
	 * @param wb        被拼接的sheet页所在的工作簿
	 * @param newSheet  被拼接的sheet页
	 * @param fromSheet 数据来源
	 * @param copyStyle 是否复制样式
	 * @param interval  两个sheet上下间隔
	 * @author hnst
	 */
	public void mergeHSSFSheet(HSSFWorkbook wb, HSSFSheet newSheet, HSSFSheet fromSheet, boolean copyStyle,
			int interval) {
		try {
			if (interval < 0) {
				throw new IllegalArgumentException("intterval:" + interval + "  间隔行数必须为正整数");
			}
			int maxColumnNum = 0;
			int lastRow = newSheet.getLastRowNum() + interval;
			//int lastRow = fromSheet.getLastRowNum() + interval;
			Map<Integer, HSSFCellStyle> styleMap = (copyStyle) ? new HashMap<Integer, HSSFCellStyle>() : null;
			for (int i = fromSheet.getFirstRowNum(); i <= fromSheet.getLastRowNum(); i++) {
				HSSFRow srcRow = fromSheet.getRow(i);
				HSSFRow destRow = newSheet.createRow(lastRow + i);
				if (srcRow != null) {
					// 复制行
					this.copyRow(wb, fromSheet, newSheet, srcRow, destRow, styleMap);
					if (srcRow.getLastCellNum() > maxColumnNum) {
						maxColumnNum = srcRow.getLastCellNum();
					}
				}
			}
			// 设置列宽
			for (int i = 0; i <= maxColumnNum; i++) { 
				newSheet.setColumnWidth(i, fromSheet.getColumnWidth(i));
			}
			// 复制图片
			this.copyPicture(wb, newSheet, fromSheet, lastRow);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		} finally {
			mergedRegions.clear();
		}
	}

	public void copySheets(HSSFWorkbook wb, HSSFSheet newSheet, HSSFSheet sheet, boolean copyStyle) {
		int maxColumnNum = 0;
		Map<Integer, HSSFCellStyle> styleMap = (copyStyle) ? new HashMap<Integer, HSSFCellStyle>() : null;
		for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {
			HSSFRow srcRow = sheet.getRow(i);
			HSSFRow destRow = newSheet.createRow(i);
			if (srcRow != null) {
				this.copyRow(wb, sheet, newSheet, srcRow, destRow, styleMap);
				if (srcRow.getLastCellNum() > maxColumnNum) {
					maxColumnNum = srcRow.getLastCellNum();
				}
			}
		}
		for (int i = 0; i <= maxColumnNum; i++) { // 设置列宽
			newSheet.setColumnWidth(i, sheet.getColumnWidth(i));
		}
	}

	/**
	 * 复制并合并单元格
	 * 
	 * @param newSheet
	 * @param sheet
	 * @param copyStyle
	 */
	public void copyRow(HSSFWorkbook wb, HSSFSheet srcSheet, HSSFSheet destSheet, HSSFRow srcRow, HSSFRow destRow,
			Map<Integer, HSSFCellStyle> styleMap) {

		destRow.setHeight(srcRow.getHeight());
		int deltaRows = destRow.getRowNum() - srcRow.getRowNum(); // 如果copy到另一个sheet的起始行数不同
		for (int j = srcRow.getFirstCellNum(); j <= srcRow.getLastCellNum(); j++) {
			HSSFCell oldCell = srcRow.getCell(j); // old cell
			HSSFCell newCell = destRow.getCell(j); // new cell
			if (oldCell != null) {
				if (newCell == null) {
					newCell = destRow.createCell(j);
				}
				copyCell(wb, oldCell, newCell, styleMap);
				CellRangeAddress mergedRegion = getMergedRegion(srcSheet, srcRow.getRowNum(),
						(short) oldCell.getColumnIndex());
				if (mergedRegion != null) {
					CellRangeAddress newMergedRegion = new CellRangeAddress(mergedRegion.getFirstRow() + deltaRows,
							mergedRegion.getLastRow() + deltaRows, mergedRegion.getFirstColumn(),
							mergedRegion.getLastColumn());
					StringBuilder stringBuilder = new StringBuilder();
					// 判断单元格是否已经合并
					String str = stringBuilder.append(newMergedRegion.getFirstColumn()).append(",")
							.append(newMergedRegion.getLastColumn()).append(",").append(newMergedRegion.getFirstRow())
							.append(",").append(newMergedRegion.getLastRow()).toString();
					if (!mergedRegions.contains(str)) {
						mergedRegions.add(str);
						destSheet.addMergedRegion(newMergedRegion);
					}

				}
			}
		}
	}

	/**
	 * 把原来的Sheet中cell（列）的样式和数据类型复制到新的sheet的cell（列）中
	 * 
	 * @param oldCell
	 * @param newCell
	 * @param styleMap
	 */
	@SuppressWarnings("deprecation")
	public void copyCell(HSSFWorkbook wb, HSSFCell oldCell, HSSFCell newCell, Map<Integer, HSSFCellStyle> styleMap) {
		if (styleMap != null) {
			if (oldCell.getSheet().getWorkbook() == newCell.getSheet().getWorkbook()) {
				newCell.setCellStyle(oldCell.getCellStyle());
			} else {
				int stHashCode = oldCell.getCellStyle().hashCode();
				HSSFCellStyle newCellStyle = styleMap.get(stHashCode);
				if (newCellStyle == null) {
					newCellStyle = newCell.getSheet().getWorkbook().createCellStyle();
					newCellStyle.cloneStyleFrom(oldCell.getCellStyle());
					if (oldCell.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
						// 处理日期格式
						newCellStyle.setDataFormat(
								wb.getCreationHelper().createDataFormat().getFormat(this.getDateFormat()));
					}
					styleMap.put(stHashCode, newCellStyle);
				}
				newCell.setCellStyle(newCellStyle);
			}
		}
		switch (oldCell.getCellType()) {
		case HSSFCell.CELL_TYPE_STRING:
			newCell.setCellValue(oldCell.getStringCellValue());
			break;
		case HSSFCell.CELL_TYPE_NUMERIC:
			newCell.setCellValue(oldCell.getNumericCellValue());
			break;
		case HSSFCell.CELL_TYPE_BLANK:
			newCell.setCellType(HSSFCell.CELL_TYPE_BLANK);
			break;
		case HSSFCell.CELL_TYPE_BOOLEAN:
			newCell.setCellValue(oldCell.getBooleanCellValue());
			break;
		case HSSFCell.CELL_TYPE_ERROR:
			newCell.setCellErrorValue(oldCell.getErrorCellValue());
			break;
		case HSSFCell.CELL_TYPE_FORMULA:
			newCell.setCellFormula(oldCell.getCellFormula());
			break;
		default:
			break;
		}

	}

	// 获取merge对象
	public CellRangeAddress getMergedRegion(HSSFSheet sheet, int rowNum, short cellNum) {
		for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
			CellRangeAddress merged = sheet.getMergedRegion(i);
			if (merged.isInRange(rowNum, cellNum)) {
				return merged;
			}
		}
		return null;
	}

	// 复制图片
	public void copyPicture(HSSFWorkbook wb, HSSFSheet newsheet, HSSFSheet sheet, int interval) {

		HSSFPatriarch newhfp = newsheet.createDrawingPatriarch();

		HSSFPatriarch hfp = sheet.getDrawingPatriarch();
		List<HSSFShape> hssfShapList = hfp.getChildren();
		// 遍历所有shape,处理图片
		for (HSSFShape hssfShape : hssfShapList) {
			if (hssfShape instanceof HSSFPicture) {
				HSSFPicture picture = (HSSFPicture) hssfShape;
				HSSFClientAnchor cAnchor = picture.getClientAnchor();
				HSSFPictureData picData = picture.getPictureData();
				byte[] pData = picData.getData();

				HSSFClientAnchor newAnchor = newhfp.createAnchor(cAnchor.getDx1(), cAnchor.getDy1(), cAnchor.getDx2(),
						cAnchor.getDy2(), cAnchor.getCol1(), cAnchor.getRow1() + interval, cAnchor.getCol2(),
						cAnchor.getRow2() + interval);

				newhfp.createPicture(newAnchor, wb.addPicture(pData, 6));

			}
		}
	}

	public String getDateFormat() {
		return dateFormat;
	}

	public void setDateFormat(String dateFormat) {
		this.dateFormat = dateFormat;
	}

}
