package com.chenyang.nse.bussiness.tools.excel;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
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.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelTool {
   public static final String OFFICE_EXCEL_XLS = "xls";
   public static final String OFFICE_EXCEL_XLSX = "xlsx";

   public static String readExcel(String filepath, Integer sheetNo, String delimit, String quotecharacter, String rowdelimiter) throws EncryptedDocumentException, InvalidFormatException, IOException {
      String sb = "";
      Workbook workbook = getWorkbook(filepath);
      if (workbook != null) {
         Sheet sheet = workbook.getSheetAt(sheetNo);
         if (sheet != null) {
            sb = readExcelSheet(sheet, delimit, quotecharacter, rowdelimiter);
         }
      }

      return sb;
   }

   private static Workbook getWorkbook(String filepath) throws EncryptedDocumentException, InvalidFormatException, IOException {
      InputStream is = null;
      Workbook wb = null;
      if (StringUtils.isBlank(filepath)) {
         throw new IllegalArgumentException("文件路径不能为空");
      } else {
         String suffiex = getSuffiex(filepath);
         if (StringUtils.isBlank(suffiex)) {
            throw new IllegalArgumentException("文件后缀不能为空");
         } else if (!"xls".equals(suffiex) && !"xlsx".equals(suffiex)) {
            throw new IllegalArgumentException("该文件非Excel文件");
         } else {
            try {
               is = new FileInputStream(filepath);
               wb = WorkbookFactory.create(is);
            } finally {
               if (is != null) {
                  is.close();
               }

               if (wb != null) {
                  wb.close();
               }

            }

            return wb;
         }
      }
   }

   private static String readExcelSheet(Sheet sheet, String delimit, String quotecharacter, String rowdelimiter) {
      StringBuilder sBuilder = new StringBuilder("");
      if (sheet != null) {
         int rowNos = sheet.getLastRowNum() + 1;

         for(int i = 0; i <= rowNos; ++i) {
            Row row = sheet.getRow(i);
            if (row != null) {
               int columNos = row.getLastCellNum();

               for(int j = 0; j < columNos; ++j) {
                  sBuilder.append(row.getCell(j));
                  Cell cell = row.getCell(j);
                  cell.setCellType(1);
                  String cellValue = cell.getStringCellValue();
                  if (j < columNos - 1) {
                     sBuilder.append(delimit);
                  }
               }

               sBuilder.append(rowdelimiter);
            }
         }
      }

      return sBuilder.toString();
   }

   private static String getSuffiex(String filepath) {
      if (StringUtils.isBlank(filepath)) {
         return "";
      } else {
         int index = filepath.lastIndexOf(".");
         return index == -1 ? "" : filepath.substring(index + 1, filepath.length());
      }
   }

   public static void generateExcel(XSSFWorkbook wb, String path, LinkedBlockingQueue queue, Map<String, String> titlevalue, List<Integer> columnWidthList, List<Integer> mergeCellArray, String sheetname) throws Exception {
      XSSFSheet sh = wb.createSheet(sheetname);
      sh.createFreezePane(0, 1, 0, 1);
      XSSFRow row = sh.createRow(0);
      row.setHeightInPoints(20.0F);
      Cell cell = null;
      XSSFCellStyle style = wb.createCellStyle();
      XSSFColor color = new XSSFColor();
      color.setARGBHex("4F81BD");
      style.setFillForegroundColor(color);
      style.setFillPattern((short)1);
      style.setVerticalAlignment(VerticalAlignment.CENTER);
      color = new XSSFColor();
      color.setARGBHex("9EB6CE");
      style.setBorderBottom((short)1);
      style.setBottomBorderColor(color);
      style.setBorderLeft((short)1);
      style.setLeftBorderColor(color);
      style.setBorderRight((short)1);
      style.setRightBorderColor(color);
      style.setBorderTop((short)1);
      style.setTopBorderColor(color);
      XSSFFont font = wb.createFont();
      font.setFontHeight((double)11.0F);
      font.setFontName("微软雅黑");
      font.setColor(IndexedColors.WHITE.index);
      style.setFont(font);
      int cellnum = 0;

      for(Map.Entry entry : titlevalue.entrySet()) {
         String title = entry.getKey().toString();
         cell = row.createCell(cellnum);
         cell.setCellValue(title);
         cell.setCellStyle(style);
         ++cellnum;
      }

      int rownum = 1;
      cellnum = 0;
      style = wb.createCellStyle();
      XSSFFont cellFont = wb.createFont();
      cellFont.setFontHeight((double)11.0F);
      style.setFont(cellFont);
      style.setBorderBottom((short)1);
      style.setBottomBorderColor(color);
      style.setBorderLeft((short)1);
      style.setLeftBorderColor(color);
      style.setBorderRight((short)1);
      style.setRightBorderColor(color);
      style.setBorderTop((short)1);
      style.setTopBorderColor(color);
      color = new XSSFColor();
      color.setARGBHex("DBE5F1");
      style.setFillForegroundColor(color);
      style.setFillPattern((short)1);
      style.setVerticalAlignment(VerticalAlignment.CENTER);

      while(queue.peek() != null) {
         Object o = queue.poll();
         ExcelRow er = getExcelRow(o, titlevalue);
         row = sh.createRow(rownum);
         er.getRowbackgroundcolor();

         for(String item : er.getCellvalue()) {
            cell = row.createCell(cellnum);
            cell.setCellValue(item);
            cell.setCellStyle(style);
            ++cellnum;
         }

         ++rownum;
         cellnum = 0;
      }

      if (mergeCellArray != null) {
         int i = 0;

         while(i < mergeCellArray.size()) {
            sh.addMergedRegion(new CellRangeAddress((Integer)mergeCellArray.get(i++), (Integer)mergeCellArray.get(i++), (Integer)mergeCellArray.get(i++), (Integer)mergeCellArray.get(i++)));
         }
      }

      for(int i = 0; i < titlevalue.size(); ++i) {
         sh.setColumnWidth(i, (Integer)columnWidthList.get(i));
      }

      FileOutputStream os = new FileOutputStream(path);
      wb.write(os);
      os.close();
   }

   public static void gettxtExcel(String path, LinkedBlockingQueue<HashMap<String, String>> queue, Map<String, String> titlevalue, List<Integer> columnWidthList, List<Integer> mergeCellArray) throws Exception {
      XSSFWorkbook wb = new XSSFWorkbook();
      XSSFSheet sh = wb.createSheet();
      XSSFRow row = sh.createRow(0);
      Cell cell = null;
      XSSFCellStyle style = wb.createCellStyle();
      XSSFColor color = new XSSFColor();
      color.setARGBHex("4F81BD");
      style.setFillForegroundColor(color);
      style.setFillPattern((short)1);
      style.setVerticalAlignment(VerticalAlignment.CENTER);
      color = new XSSFColor();
      color.setARGBHex("9EB6CE");
      style.setBorderBottom((short)1);
      style.setBottomBorderColor(color);
      style.setBorderLeft((short)1);
      style.setLeftBorderColor(color);
      style.setBorderRight((short)1);
      style.setRightBorderColor(color);
      style.setBorderTop((short)1);
      style.setTopBorderColor(color);
      XSSFFont font = wb.createFont();
      font.setFontHeight((double)11.0F);
      font.setFontName("微软雅黑");
      font.setColor(IndexedColors.WHITE.index);
      style.setFont(font);
      int cellnum = 0;
      Iterator it = titlevalue.entrySet().iterator();
      int rownum = 0;
      cellnum = 0;
      style = wb.createCellStyle();
      XSSFFont cellFont = wb.createFont();
      cellFont.setFontHeight((double)11.0F);
      style.setFont(cellFont);
      style.setBorderBottom((short)1);
      style.setBottomBorderColor(color);
      style.setBorderLeft((short)1);
      style.setLeftBorderColor(color);
      style.setBorderRight((short)1);
      style.setRightBorderColor(color);
      style.setBorderTop((short)1);
      style.setTopBorderColor(color);
      color = new XSSFColor();
      color.setARGBHex("DBE5F1");
      style.setFillForegroundColor(color);
      style.setFillPattern((short)1);
      style.setVerticalAlignment(VerticalAlignment.CENTER);

      while(queue.peek() != null) {
         Object o = queue.poll();
         ExcelRow er = getExcelRow(o, titlevalue);
         row = sh.createRow(rownum);
         er.getRowbackgroundcolor();

         for(String item : er.getCellvalue()) {
            cell = row.createCell(cellnum);
            cell.setCellValue(item);
            cell.setCellStyle(style);
            ++cellnum;
         }

         ++rownum;
         cellnum = 0;
      }

      if (mergeCellArray != null) {
         int i = 0;

         while(i < mergeCellArray.size()) {
            sh.addMergedRegion(new CellRangeAddress((Integer)mergeCellArray.get(i++), (Integer)mergeCellArray.get(i++), (Integer)mergeCellArray.get(i++), (Integer)mergeCellArray.get(i++)));
         }
      }

      for(int i = 0; i < titlevalue.size(); ++i) {
         sh.setColumnWidth(i, (Integer)columnWidthList.get(i));
      }

      FileOutputStream os = new FileOutputStream(path);
      wb.write(os);
      os.close();
   }

   public static ExcelRow getExcelRow(Object obj, Map<String, String> titlevalue) throws Exception {
      Map<String, String> map = (Map)obj;
      List<String> cellvalue = new ArrayList();

      for(Map.Entry entry : titlevalue.entrySet()) {
         String key = entry.getKey().toString();
         String value = entry.getValue().toString();
         cellvalue.add(map.get(value) == null ? "" : ((String)map.get(value)).toString());
      }

      ExcelRow er = new ExcelRow();
      er.setCellvalue(cellvalue);
      return er;
   }

   public static void main(String[] args) {
   }
}
