创建默认普通单元格样式

<pre>
1. 文字上下左右居中
2. 细边框，黑色
</pre>

@param workbook {@link Workbook} 工作簿
@return {@link CellStyle}
482614
public static CellStyle createDefaultCellStyle(Workbook workbook) {
		final CellStyle cellStyle = workbook.createCellStyle();
		setAlign(cellStyle, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
		setBorder(cellStyle, BorderStyle.THIN, IndexedColors.BLACK);
		return cellStyle;
	}
1017086
public static Workbook newWorkbook() {
        Workbook book = new XSSFWorkbook();
        book.addToolPack(Functions.getUdfFinder());
        return book;
    }
58161
public static <T> List<T> handleWorkBookToBeans(Class<T> clazz, File file) throws ReadExcelException {
        List<T> beans = null;
        try {
            Workbook workbook = WorkbookFactory.create(file);
            beans = ReadExcelUtils.handleWorkBookToBeans(clazz, workbook);
            if (workbook != null) {
                workbook.close();
            }
        } catch (Exception e) {
            throw new ReadExcelException(e.getMessage());
        }
        return beans;
    }
459108
public static CellStyle cloneCellStyle(Cell cell, CellStyle cellStyle) {
		return cloneCellStyle(cell.getSheet().getWorkbook(), cellStyle);
	}
816424
public String getCell(String row, String col) throws Exception {
		if (col.equals(this.getIndexColumnName())) {
			return row;
		}
		HeaderInfo rowIndex = rowLookup.get(row);
		HeaderInfo colIndex = columnLookup.get(col);

		if (rowIndex == null) {
			//allow for case insentive search
			for (String rowtable : rowLookup.keySet()) {
				if (row.equalsIgnoreCase(rowtable)) {
					rowIndex = rowLookup.get(rowtable);
					break;
				}
			}
			if (rowIndex == null) {
				throw new Exception("Row " + row + " not found in worksheet");
			}
		}
		if (colIndex == null) {
			//allow for case insentive search
			for (String coltable : columnLookup.keySet()) {
				if (col.equalsIgnoreCase(coltable)) {
					colIndex = columnLookup.get(coltable);
					break;
				}
			}
			if (colIndex == null) {
				throw new Exception("Column " + col + " not found in worksheet");
			}
		}

		CompactCharSequence ccs = data[rowIndex.getIndex()][colIndex.getIndex()];
		if (ccs != null) {
			return ccs.toString();
		} else {
			return "";
		}

		// return .toString();
	}
1209917
public static CellStyle cloneCellStyle(Workbook workbook, CellStyle cellStyle) {
		final CellStyle newCellStyle = workbook.createCellStyle();
		newCellStyle.cloneStyleFrom(cellStyle);
		return newCellStyle;
	}
1256718
public static List<?> workbook2List(ExcelConfig config, Workbook wb) throws Exception {
        String[] names = config.getNames();
        String[] types = config.getTypes();
        Field key = config.getKey();

        List<Object> list = new ArrayList<Object>();
        Sheet sheet = wb.getSheet(config.getSheetNum());
        int length = sheet.getColumns() < names.length ? sheet.getColumns() : names.length;
        //计算行数
        int rowLength = sheet.getRows() < config.getMaxRow() ?
                sheet.getRows() : (config.getMaxRow() > 0 ? (config.getMaxRow() + config.getStartRow()) : sheet.getRows());

        for (int i = config.getStartRow(); i < rowLength; i++) {
            //Map类型要特殊处理
            Class clazz = Class.forName(config.getClazz());
            Object obj = null;
            if (Map.class.isAssignableFrom(clazz)) {
                obj = new HashMap();
            } else {
                obj = clazz.newInstance();
            }
            for (int j = 0; j < length; j++) {
                setValue(obj, names[j], types[j], sheet.getCell(j, i));
            }
            //checkKey
            if (key != null) {
                //当主键为空时，不在继续读取excel
                if (key.get(obj) == null || "".equals(String.valueOf(key.get(obj)))) {
                    break;
                }
            }
            list.add(obj);
        }
        return list;
    }
256118
public Workbook writeToExcel(List<? extends Object> datas, boolean hasTitle, Workbook workbook,
                                 boolean transverse) {
        if (CollectionUtil.safeIsEmpty(datas)) {
            log.warn("给定数据集合为空");
            return workbook;
        }
        datas = datas.parallelStream().filter(data -> data != null).collect(Collectors.toList());
        if (datas.isEmpty()) {
            log.warn("给定数据集合里的数据全是空");
            return workbook;
        }
        //获取所有字段（包括父类的）
        Field[] fields = ReflectUtil.getAllFields(datas.get(0).getClass());

        log.info("获取可写入excel的字段");
        List<Field> writeFields = new ArrayList<>();
        for (Field field : fields) {
            String name = field.getName();
            log.debug("检查字段[{}]是否可以写入", name);
            Class<?> type = field.getType();

            List<ExcelDataWriter<?>> data = writers.values().stream()
                .filter(excelData -> excelData.writeable(type)).collect(Collectors.toList());
            if (data.isEmpty()) {
                log.info("字段[{}]不能写入", name);
            } else {
                log.info("字段[{}]可以写入excel");
                ExcelColumn column = field.getAnnotation(ExcelColumn.class);

                if (column == null || !column.ignore()) {
                    writeFields.add(field);
                }
            }
        }
        log.debug("可写入excel的字段集合为：[{}]", writeFields);
        log.debug("对可写入excel的字段集合排序");

        Collections.sort(writeFields, COMPARATOR);

        log.debug("可写入excel的字段集合排序完毕，构建标题列表");

        List<Writer<?>> titles = null;
        if (hasTitle) {
            log.info("当前需要标题列表，构建...");
            titles = new ArrayList<>(writeFields.size());
            for (int i = 0; i < writeFields.size(); i++) {
                Field field = writeFields.get(i);
                ExcelColumn column = field.getAnnotation(ExcelColumn.class);
                if (column == null || StringUtils.isEmpty(column.value())) {
                    titles.add(build(field.getName()));
                } else {
                    titles.add(build(column.value()));
                }
            }
        }

        log.debug("构建单元格数据");
        List<List<Writer<?>>> writeDatas = new ArrayList<>(datas.size());
        for (int i = 0; i < datas.size(); i++) {
            Object dataValue = datas.get(i);
            //构建一行数据
            List<Writer<?>> columnDatas = new ArrayList<>(writeFields.size());
            //加入
            writeDatas.add(columnDatas);
            for (int j = 0; j < writeFields.size(); j++) {
                Field field = writeFields.get(j);
                try {
                    log.debug("获取[{}]中字段[{}]的值", dataValue, field.getName());
                    Object value = field.get(dataValue);
                    columnDatas.add(build(value));
                } catch (IllegalAccessException e) {
                    log.warn("[{}]中字段[{}]不能读取", dataValue, field.getName(), e);
                    columnDatas.add(null);
                }
            }
        }

        log.debug("要写入的数据为：[{}]", writeDatas);
        log.info("准备写入数据");
        writeToExcel(titles, writeDatas, hasTitle, workbook, transverse);
        log.info("标题列表为：[{}]", titles);
        return workbook;
    }
691909
public static void copyCell(XSSFCell oldCell, XSSFCell newCell, Map<Integer, CellStyle> styleMap) {
		if (styleMap != null) {			
			if (oldCell.getSheet().getWorkbook() == newCell.getSheet().getWorkbook()) {
				newCell.setCellStyle(oldCell.getCellStyle());
			} else {				
				int stHashCode = oldCell.getCellStyle().hashCode();
				CellStyle newCellStyle = styleMap.get(stHashCode);				
				if (newCellStyle == null) {					
					newCellStyle = newCell.getSheet().getWorkbook().createCellStyle();
					newCellStyle.cloneStyleFrom(oldCell.getCellStyle());					
					styleMap.put(stHashCode, newCellStyle);
				}
				newCell.setCellStyle(newCellStyle);
			}			
		}
		switch (oldCell.getCellType()) {
		case XSSFCell.CELL_TYPE_STRING:
			newCell.setCellValue(oldCell.getStringCellValue());
			break;
		case XSSFCell.CELL_TYPE_NUMERIC:
			newCell.setCellValue(oldCell.getNumericCellValue());
			break;
		case XSSFCell.CELL_TYPE_BLANK:
			newCell.setCellType(XSSFCell.CELL_TYPE_BLANK);
			break;
		case XSSFCell.CELL_TYPE_BOOLEAN:
			newCell.setCellValue(oldCell.getBooleanCellValue());
			break;
		case XSSFCell.CELL_TYPE_ERROR:
			newCell.setCellErrorValue(oldCell.getErrorCellValue());
			break;
		case XSSFCell.CELL_TYPE_FORMULA:
			newCell.setCellFormula(oldCell.getCellFormula());
			break;
		default:
			break;
		}

	}
551564
public static Collection<Row> getRowsFromsCells(Collection<Cells> cellsCol) {
        Collection<Row> result = new ArrayList<>();
        for (Cells cells : cellsCol) {
            result.add(getRowFromCells(cells));
        }
        return result;
    }
237143
public static boolean isDateStart1904(final Workbook workbook) {

        if(workbook instanceof HSSFWorkbook) {
            try {
                Method method = HSSFWorkbook.class.getDeclaredMethod("getWorkbook");
                method.setAccessible(true);

                InternalWorkbook iw = (InternalWorkbook) method.invoke(workbook);
                return iw.isUsing1904DateWindowing();

            } catch(NoSuchMethodException | SecurityException e) {
                logger.warn("fail access method HSSFWorkbook.getWorkbook.", e);
                return false;
            } catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                logger.warn("fail invoke method HSSFWorkbook.getWorkbook.", e);
                return false;
            }

        } else if(workbook instanceof XSSFWorkbook) {
            try {
                Method method = XSSFWorkbook.class.getDeclaredMethod("isDate1904");
                method.setAccessible(true);

                boolean value = (boolean) method.invoke(workbook);
                return value;

            } catch(NoSuchMethodException | SecurityException e) {
                logger.warn("fail access method XSSFWorkbook.isDate1904.", e);
                return false;
            } catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                logger.warn("fail invoke method XSSFWorkbook.isDate1904.", e);
                return false;
            }

        } else {
            logger.warn("unknown workbook type.", workbook.getClass().getName());
        }

        return false;
    }
1185627
public Workbook writeToExcel(List<? extends Object> datas, boolean hasTitle,
                                 Workbook workbook) {
        return writeToExcel(datas, hasTitle, workbook, false);
    }
842358
private String formatCell(Cell cell) {
        lock.lock();
        try {
            return dataFormatter.formatCellValue(cell);
        } finally {
            lock.unlock();
        }
    }
929748
public CellFormatResult format(final ObjectCell<?> cell, final Locale locale) {
        
        if(cell == null) {
            final CellFormatResult result = new CellFormatResult();
            result.setCellType(FormatCellType.Blank);
            result.setText("");
            return result;
        }
        
        final Locale runtimeLocale = locale != null ? locale : Locale.getDefault();
        
        final short formatIndex = cell.getFormatIndex();
        final String formatPattern = cell.getFormatPattern();
        
        if(formatterResolver.canResolve(formatIndex)) {
            final CellFormatter cellFormatter = formatterResolver.getFormatter(formatIndex);
            return cellFormatter.format(cell, runtimeLocale);
            
        } else if(formatterResolver.canResolve(formatPattern)) {
            final CellFormatter cellFormatter = formatterResolver.getFormatter(formatPattern);
            return cellFormatter.format(cell, runtimeLocale);
            
        } else {
            // キャッシュに存在しない場合
            final CellFormatter cellFormatter = formatterResolver.createFormatter(formatPattern) ;
            if(isCache()) {
                formatterResolver.registerFormatter(formatPattern, cellFormatter);
            }
            return cellFormatter.format(cell, runtimeLocale);
            
        }
    }
211389
public static Workbook getWorkbook(File file) throws IOException
    {
        Workbook ret = null;
        String lowerFilename = file.getName().toLowerCase();
        if(lowerFilename.endsWith("."+CommonFiles.XLS_EXT))
        {
            ret = XlsWorkbook.getWorkbook(file);
        }
        else if(lowerFilename.endsWith("."+CommonFiles.XLSX_EXT))
        {
            XlsxWorkbook.initJaxbContexts();
            ret = XlsxWorkbook.getWorkbook(file);
        }
        return ret;
    }
687201
public static BorderStyle getBorderTop(final Cell cell) {

        ArgUtils.notNull(cell, "cell");

        final Sheet sheet = cell.getSheet();
        CellRangeAddress mergedRegion = getMergedRegion(sheet, cell.getRowIndex(), cell.getColumnIndex());

        final Cell target;
        if(mergedRegion == null) {
            // 結合されていない場合
            target = cell;

        } else {
            if(mergedRegion.getFirstRow() == cell.getRowIndex()) {
                // 引数のCellが上部のセルの場合
                target = cell;
            } else {
                target = getCell(sheet, cell.getColumnIndex(), mergedRegion.getFirstRow());
            }

        }

        final CellStyle style = target.getCellStyle();
        if(style == null) {
            return BorderStyle.NONE;
        } else {
            return style.getBorderTopEnum();
        }

    }
433869
public static List<Object> readRow(Row row, CellEditor cellEditor) {
		if (null == row) {
			return new ArrayList<>(0);
		}
		final short length = row.getLastCellNum();
		if (length < 0) {
			return new ArrayList<>(0);
		}
		final List<Object> cellValues = new ArrayList<>((int) length);
		Object cellValue;
		boolean isAllNull = true;
		for (short i = 0; i < length; i++) {
			cellValue = CellUtil.getCellValue(row.getCell(i), cellEditor);
			isAllNull &= StrUtil.isEmptyIfStr(cellValue);
			cellValues.add(cellValue);
		}

		if (isAllNull) {
			// 如果每个元素都为空，则定义为空行
			return new ArrayList<>(0);
		}
		return cellValues;
	}