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

import com.chenyang.nse.bussiness.entity.orm.table.base.TBaseUser;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
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.openxml4j.util.ZipSecureFile;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
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.streaming.SXSSFWorkbook;
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 void main(String[] args) throws Exception {
      LinkedBlockingQueue<TBaseUser> queue = new LinkedBlockingQueue();

      for(int i = 0; i < 100; ++i) {
         TBaseUser tu = new TBaseUser();
         tu.setCreatetime(new Date());
         tu.setId(UUID.randomUUID().toString());
         tu.setNote("创建人" + i);
         tu.setPassword(UUID.randomUUID().toString());
         tu.setUsername(UUID.randomUUID().toString());
         queue.put(tu);
      }

      Map<String, String> titlevalue = new LinkedHashMap();
      titlevalue.put("创建时间", "createtime");
      titlevalue.put("主键", "id");
      titlevalue.put("备注", "note");
      titlevalue.put("密码", "password");
      titlevalue.put("用户名", "username");

      try {
         generateExcel("C:/Users/Administrator/Desktop/aa.xlsx", queue, titlevalue);
      } catch (Exception e) {
         e.printStackTrace();
      }

   }

   public static void generateExcel(String path, LinkedBlockingQueue quene, Map<String, String> titlevalue) throws Exception {
      SXSSFWorkbook wb = new SXSSFWorkbook(100);
      Sheet sh = wb.createSheet();
      sh.setDefaultColumnWidth(50);
      sh.protectSheet(new String("ghca"));
      Row row = sh.createRow(0);
      Cell cell = null;
      CellStyle style = wb.createCellStyle();
      style.setLocked(true);
      Font font = wb.createFont();
      font.setFontHeightInPoints((short)11);
      font.setFontName("等线");
      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;
      CellStyle unlockStyle = wb.createCellStyle();
      unlockStyle.setFont(font);
      unlockStyle.setLocked(false);

      while(quene.peek() != null) {
         Object o = quene.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(unlockStyle);
            ++cellnum;
         }

         ++rownum;
         cellnum = 0;
      }

      ZipSecureFile.setMinInflateRatio(1.0E-7);
      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 generateExcel(String path, LinkedBlockingQueue queue, Map<String, String> titlevalue, List<Integer> columnWidthList, List<Integer> mergeCellArray) throws Exception {
      XSSFWorkbook wb = new XSSFWorkbook();
      XSSFSheet sh = wb.createSheet();
      sh.createFreezePane(0, 1, 0, 1);
      sh.protectSheet(new String("ghca"));
      XSSFRow row = sh.createRow(0);
      row.setHeightInPoints(20.0F);
      Cell cell = null;
      XSSFCellStyle style = wb.createCellStyle();
      style.setLocked(true);
      new XSSFColor();
      style.setVerticalAlignment(VerticalAlignment.CENTER);
      style.setAlignment((short)2);
      XSSFFont font = wb.createFont();
      font.setFontHeight((double)11.0F);
      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);
      CellStyle unlockStyle = wb.createCellStyle();
      unlockStyle.setFont(font);
      unlockStyle.setLocked(false);

      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);
            if (cellnum != 7 && cellnum != 9 && cellnum != 10) {
               cell.setCellStyle(style);
            } else {
               cell.setCellStyle(unlockStyle);
            }

            ++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) {
         if ((Integer)columnWidthList.get(i) == -100) {
            sh.setColumnWidth(i, 0);
         } else {
            sh.setColumnWidth(i, (Integer)columnWidthList.get(i));
         }
      }

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

   public static void generateSheetExcel(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.autoSizeColumn(i);
      }

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

   public static List<List<String>> readExcel(String filepath, Integer sheetNo) throws EncryptedDocumentException, InvalidFormatException, IOException {
      List<List<String>> sb = new ArrayList();
      Workbook workbook = getWorkbook(filepath);
      if (workbook != null) {
         Sheet sheet = workbook.getSheetAt(sheetNo);
         if (sheet != null) {
            sb = readExcelSheet(sheet);
         }
      }

      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 List<List<String>> readExcelSheet(Sheet sheet) {
      List<List<String>> listall = new ArrayList();
      if (sheet != null) {
         int rowNos = sheet.getLastRowNum() + 1;
         int linenum = sheet.getRow(0).getLastCellNum();

         for(int i = 1; i < rowNos; ++i) {
            List<String> list = new ArrayList();
            Row row = sheet.getRow(i);
            if (row != null) {
               for(int j = 0; j < linenum && row.getCell(0) != null; ++j) {
                  if (null != row.getCell(j)) {
                     list.add(row.getCell(j).getStringCellValue());
                  } else {
                     list.add(null);
                  }
               }

               if (list.size() > 0) {
                  listall.add(list);
               }
            }
         }
      }

      return listall;
   }

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