package cc.mrbird.febs.common.utils.excl;
|
|
import cn.hutool.core.util.ArrayUtil;
|
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.lang.ArrayUtils;
|
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
|
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
import org.apache.poi.ss.usermodel.*;
|
import org.apache.poi.ss.util.CellRangeAddress;
|
import org.apache.poi.ss.util.WorkbookUtil;
|
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
import java.io.*;
|
import java.text.DecimalFormat;
|
import java.text.SimpleDateFormat;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.LinkedList;
|
import java.util.List;
|
|
/**
|
* excel工具类 提供读取和写入excel的功能
|
*
|
* @author JIANGYOUYAO
|
* @email 935090232@qq.com
|
* @date 2017年12月20日
|
*/
|
public class ExcelUtil {
|
|
/**
|
* 标题样式
|
*/
|
private final static String STYLE_HEADER = "header";
|
/**
|
* 表头样式
|
*/
|
private final static String STYLE_TITLE = "title";
|
/**
|
* 数据样式
|
*/
|
private final static String STYLE_DATA = "data";
|
|
private static String getFileExtName(File file) {
|
String fileName = file.getName();
|
String prefix = fileName.substring(fileName.lastIndexOf(".") );
|
return prefix;
|
}
|
|
/**
|
* 读取excel文件里面的内容 支持日期,数字,字符,函数公式,布尔类型
|
*
|
* @param file
|
* @param rowCount
|
* @param columnCount
|
* @return
|
* @throws FileNotFoundException
|
* @throws IOException
|
* @author JIANGYOUYAO
|
* @email 935090232@qq.com
|
* @date 2017年12月20日
|
*/
|
public static List<ExcelSheetPO> readExcel(File file, Integer rowCount, Integer columnCount)
|
throws FileNotFoundException, IOException {
|
|
// 根据后缀名称判断excel的版本
|
String extName = getFileExtName(file);
|
Workbook wb = null;
|
if (ExcelVersion.V2003.getSuffix().equals(extName)) {
|
wb = new HSSFWorkbook(new FileInputStream(file));
|
|
} else if (ExcelVersion.V2007.getSuffix().equals(extName)) {
|
wb = new XSSFWorkbook(new FileInputStream(file));
|
|
} else {
|
// 无效后缀名称,这里之能保证excel的后缀名称,不能保证文件类型正确,不过没关系,在创建Workbook的时候会校验文件格式
|
throw new IllegalArgumentException("Invalid excel version");
|
}
|
// 开始读取数据
|
List<ExcelSheetPO> sheetPOs = new ArrayList<>();
|
// 解析sheet
|
for (int i = 0; i < wb.getNumberOfSheets(); i++) {
|
Sheet sheet = wb.getSheetAt(i);
|
List<List<Object>> dataList = new ArrayList<>();
|
ExcelSheetPO sheetPO = new ExcelSheetPO();
|
sheetPO.setSheetName(sheet.getSheetName());
|
sheetPO.setDataList(dataList);
|
int readRowCount = 0;
|
if (rowCount == null || rowCount > sheet.getPhysicalNumberOfRows()) {
|
readRowCount = sheet.getPhysicalNumberOfRows();
|
} else {
|
readRowCount = rowCount;
|
}
|
// 解析sheet 的行
|
for (int j = sheet.getFirstRowNum(); j < readRowCount; j++) {
|
Row row = sheet.getRow(j);
|
if (row == null) {
|
continue;
|
}
|
if (row.getFirstCellNum() < 0) {
|
continue;
|
}
|
int readColumnCount = 0;
|
if (columnCount == null || columnCount > row.getLastCellNum()) {
|
readColumnCount = (int) row.getLastCellNum();
|
} else {
|
readColumnCount = columnCount;
|
}
|
List<Object> rowValue = new LinkedList<Object>();
|
// 解析sheet 的列
|
for (int k = 0; k < readColumnCount; k++) {
|
Cell cell = row.getCell(k);
|
rowValue.add(getCellValue(wb, cell));
|
}
|
dataList.add(rowValue);
|
}
|
sheetPOs.add(sheetPO);
|
}
|
return sheetPOs;
|
}
|
|
|
|
|
|
private static Object getCellValue(Workbook wb, Cell cell) {
|
Object columnValue = null;
|
if (cell != null) {
|
// 格式化 number
|
DecimalFormat df = new DecimalFormat("0");
|
// String
|
// 字符
|
// 格式化日期字符串
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
// 格式化数字
|
DecimalFormat nf = new DecimalFormat("0.00");
|
switch (cell.getCellType()) {
|
case Cell.CELL_TYPE_STRING:
|
columnValue = cell.getStringCellValue();
|
break;
|
case Cell.CELL_TYPE_NUMERIC:
|
if ("@".equals(cell.getCellStyle().getDataFormatString())) {
|
columnValue = df.format(cell.getNumericCellValue());
|
} else if ("General".equals(cell.getCellStyle().getDataFormatString())) {
|
columnValue = nf.format(cell.getNumericCellValue());
|
} else {
|
columnValue = sdf.format(HSSFDateUtil.getJavaDate(cell.getNumericCellValue()));
|
}
|
break;
|
case Cell.CELL_TYPE_BOOLEAN:
|
columnValue = cell.getBooleanCellValue();
|
break;
|
case Cell.CELL_TYPE_BLANK:
|
columnValue = "";
|
break;
|
case Cell.CELL_TYPE_FORMULA:
|
// 格式单元格
|
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
|
evaluator.evaluateFormulaCell(cell);
|
CellValue cellValue = evaluator.evaluate(cell);
|
columnValue = cellValue.getNumberValue();
|
break;
|
default:
|
columnValue = cell.toString();
|
}
|
}
|
return columnValue;
|
}
|
|
/**
|
* 在硬盘上写入excel文件
|
*
|
* @param version
|
* @param excelSheets
|
* @param filePath
|
* @throws IOException
|
* @author JIANGYOUYAO
|
* @email 935090232@qq.com
|
* @date 2017年12月20日
|
*/
|
public static void createWorkbookAtDisk(ExcelVersion version, List<ExcelSheetPO> excelSheets, String filePath)
|
throws IOException {
|
FileOutputStream fileOut = new FileOutputStream(filePath);
|
createWorkbookAtOutStream(version, excelSheets, fileOut, true);
|
}
|
|
/**
|
* 把excel表格写入输出流中
|
*
|
* @param version
|
* @param excelSheets
|
* @param outStream
|
* @param closeStream 是否关闭输出流
|
* @throws IOException
|
* @author JIANGYOUYAO
|
* @email 935090232@qq.com
|
* @date 2017年12月20日
|
*/
|
public static void createWorkbookAtOutStream(ExcelVersion version, List<ExcelSheetPO> excelSheets,
|
OutputStream outStream, boolean closeStream) throws IOException {
|
if (CollectionUtils.isNotEmpty(excelSheets)) {
|
Workbook wb = createWorkBook(version, excelSheets);
|
wb.write(outStream);
|
if (closeStream) {
|
outStream.close();
|
}
|
}
|
}
|
|
private static Workbook createWorkBook(ExcelVersion version, List<ExcelSheetPO> excelSheets) {
|
Workbook wb = getWorkbookInstance(version);
|
for (int i = 0; i < excelSheets.size(); i++) {
|
ExcelSheetPO excelSheetPO = excelSheets.get(i);
|
if (excelSheetPO.getSheetName() == null) {
|
excelSheetPO.setSheetName("sheet" + i);
|
}
|
// 过滤特殊字符
|
Sheet tempSheet = wb.createSheet(WorkbookUtil.createSafeSheetName(excelSheetPO.getSheetName()));
|
buildSheetData(wb, tempSheet, excelSheetPO, version);
|
}
|
return wb;
|
}
|
|
private static void buildSheetData(Workbook wb, Sheet sheet, ExcelSheetPO excelSheetPO, ExcelVersion version) {
|
sheet.setDefaultRowHeight((short) 400);
|
sheet.setDefaultColumnWidth((short) 10);
|
createTitle(sheet, excelSheetPO, wb, version);
|
createHeader(sheet, excelSheetPO, wb, version);
|
createBody(sheet, excelSheetPO, wb, version);
|
}
|
|
private static void createBody(Sheet sheet, ExcelSheetPO excelSheetPO, Workbook wb, ExcelVersion version) {
|
List<List<Object>> dataList = excelSheetPO.getDataList();
|
for (int i = 0; i < dataList.size() && i < version.getMaxRow(); i++) {
|
List<Object> values = dataList.get(i);
|
Row row = sheet.createRow(2 + i);
|
for (int j = 0; j < values.size() && j < version.getMaxColumn(); j++) {
|
Cell cell = row.createCell(j);
|
Object value = values.get(j);
|
if (value == null) {
|
value = "";
|
}
|
cell.setCellValue(String.valueOf(value));
|
}
|
}
|
}
|
|
private static void createHeader(Sheet sheet, ExcelSheetPO excelSheetPO, Workbook wb, ExcelVersion version) {
|
String[] headers = excelSheetPO.getHeaders();
|
Row row = sheet.createRow(1);
|
for (int i = 0; i < headers.length && i < version.getMaxColumn(); i++) {
|
Cell cellHeader = row.createCell(i);
|
cellHeader.setCellStyle(getStyle(STYLE_HEADER, wb));
|
cellHeader.setCellValue(headers[i]);
|
}
|
|
}
|
|
private static void createTitle(Sheet sheet, ExcelSheetPO excelSheetPO, Workbook wb, ExcelVersion version) {
|
Row titleRow = sheet.createRow(0);
|
Cell titleCel = titleRow.createCell(0);
|
titleCel.setCellValue(excelSheetPO.getTitle());
|
titleCel.setCellStyle(getStyle(STYLE_TITLE, wb));
|
// 限制最大列数
|
if (ArrayUtil.isNotEmpty(excelSheetPO.getHeaders())) {
|
int column = excelSheetPO.getHeaders().length > version.getMaxColumn() ? version.getMaxColumn()
|
: excelSheetPO.getHeaders().length;
|
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, column - 1));
|
}
|
|
}
|
|
private static CellStyle getStyle(String type, Workbook wb) {
|
|
HashMap<String, CellStyle> cellStyleMap = new HashMap<>();
|
if (cellStyleMap.containsKey(type)) {
|
return cellStyleMap.get(type);
|
}
|
// 生成一个样式
|
CellStyle style = wb.createCellStyle();
|
// style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
|
// style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
|
// style.setBorderRight(HSSFCellStyle.BORDER_THIN);
|
// style.setBorderTop(HSSFCellStyle.BORDER_THIN);
|
style.setWrapText(true);
|
|
if (STYLE_HEADER == type) {
|
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
|
Font font = wb.createFont();
|
font.setFontHeightInPoints((short) 16);
|
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
|
style.setFont(font);
|
} else if (STYLE_TITLE == type) {
|
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
|
Font font = wb.createFont();
|
font.setFontHeightInPoints((short) 18);
|
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
|
style.setFont(font);
|
} else if (STYLE_DATA == type) {
|
style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
|
Font font = wb.createFont();
|
font.setFontHeightInPoints((short) 12);
|
style.setFont(font);
|
}
|
cellStyleMap.put(type, style);
|
return style;
|
}
|
|
private static Workbook getWorkbookInstance(ExcelVersion version) {
|
switch (version) {
|
case V2003:
|
return new HSSFWorkbook();
|
case V2007:
|
return new XSSFWorkbook();
|
case V_BIGDATA:
|
return new SXSSFWorkbook(2000);
|
default:
|
throw new IllegalArgumentException("param is not defind");
|
}
|
}
|
}
|