利用注解+反射优雅的实现通用Excel导入导出
Java资料站
共 20853字,需浏览 42分钟
·
2021-07-30 22:50
点击上方蓝色字体,选择“标星公众号”
优质文章,第一时间送达
/**
* 设置允许导出
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableExport {
String fileName();
}
/**
* 设置该字段允许导出
* 并且可以设置宽度
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableExportField {
int colWidth() default 100;
String colName();
}
/**
* 导入时索引
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ImportIndex {
int index() ;
}
/**
* 将Excel转换为对象集合
* @param excel Excel 文件
* @param clazz pojo类型
* @return
*/
public static List<Object> parseExcelToList(File excel,Class clazz){
List<Object> res = new ArrayList<>();
// 创建输入流,读取Excel
InputStream is = null;
Sheet sheet = null;
try {
is = new FileInputStream(excel.getAbsolutePath());
if (is != null) {
Workbook workbook = WorkbookFactory.create(is);
//默认只获取第一个工作表
sheet = workbook.getSheetAt(0);
if (sheet != null) {
//前两行是标题
int i = 2;
String values[] ;
Row row = sheet.getRow(i);
while (row != null) {
//获取单元格数目
int cellNum = row.getPhysicalNumberOfCells();
values = new String[cellNum];
for (int j = 0; j <= cellNum; j++) {
Cell cell = row.getCell(j);
if (cell != null) {
//设置单元格内容类型
cell.setCellType(Cell.CELL_TYPE_STRING );
//获取单元格值
String value = cell.getStringCellValue() == null ? null : cell.getStringCellValue();
values[j]=value;
}
}
Field[] fields = clazz.getDeclaredFields();
Object obj = clazz.newInstance();
for(Field f : fields){
if(f.isAnnotationPresent(ImportIndex.class)){
ImportIndex annotation = f.getDeclaredAnnotation(ImportIndex.class);
int index = annotation.index();
f.setAccessible(true);
//此处使用了阿里巴巴的fastjson包里面的一个类型转换工具类
Object val =TypeUtils.cast(values[index],f.getType(),null);
f.set(obj,val);
}
}
res.add(obj);
i++;
row=sheet.getRow(i);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
/**
* 获取一个基本的带边框的单元格
* @param workbook
* @return
*/
private static HSSFCellStyle getBasicCellStyle(HSSFWorkbook workbook){
HSSFCellStyle hssfcellstyle = workbook.createCellStyle();
hssfcellstyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
hssfcellstyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
hssfcellstyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
hssfcellstyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
hssfcellstyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
hssfcellstyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
hssfcellstyle.setWrapText(true);
return hssfcellstyle;
}
/**
* 获取带有背景色的标题单元格
* @param workbook
* @return
*/
private static HSSFCellStyle getTitleCellStyle(HSSFWorkbook workbook){
HSSFCellStyle hssfcellstyle = getBasicCellStyle(workbook);
hssfcellstyle.setFillForegroundColor((short) HSSFColor.CORNFLOWER_BLUE.index); // 设置背景色
hssfcellstyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
return hssfcellstyle;
}
/**
* 创建一个跨列的标题行
* @param workbook
* @param hssfRow
* @param hssfcell
* @param hssfsheet
* @param allColNum
* @param title
*/
private static void createTitle(HSSFWorkbook workbook, HSSFRow hssfRow , HSSFCell hssfcell, HSSFSheet hssfsheet,int allColNum,String title){
//在sheet里增加合并单元格
CellRangeAddress cra = new CellRangeAddress(0, 0, 0, allColNum);
hssfsheet.addMergedRegion(cra);
// 使用RegionUtil类为合并后的单元格添加边框
RegionUtil.setBorderBottom(1, cra, hssfsheet, workbook); // 下边框
RegionUtil.setBorderLeft(1, cra, hssfsheet, workbook); // 左边框
RegionUtil.setBorderRight(1, cra, hssfsheet, workbook); // 有边框
RegionUtil.setBorderTop(1, cra, hssfsheet, workbook); // 上边框
//设置表头
hssfRow = hssfsheet.getRow(0);
hssfcell = hssfRow.getCell(0);
hssfcell.setCellStyle( getTitleCellStyle(workbook));
hssfcell.setCellType(HSSFCell.CELL_TYPE_STRING);
hssfcell.setCellValue(title);
}
/**
* 设置表头标题栏以及表格高度
* @param workbook
* @param hssfRow
* @param hssfcell
* @param hssfsheet
* @param colNames
*/
private static void createHeadRow(HSSFWorkbook workbook,HSSFRow hssfRow , HSSFCell hssfcell,HSSFSheet hssfsheet,List<String> colNames){
//插入标题行
hssfRow = hssfsheet.createRow(1);
for (int i = 0; i < colNames.size(); i++) {
hssfcell = hssfRow.createCell(i);
hssfcell.setCellStyle(getTitleCellStyle(workbook));
hssfcell.setCellType(HSSFCell.CELL_TYPE_STRING);
hssfcell.setCellValue(colNames.get(i));
}
}
/**
* excel添加下拉数据校验
* @param sheet 哪个 sheet 页添加校验
* @return
*/
public static void createDataValidation(Sheet sheet,Map<Integer,String[]> selectListMap) {
if(selectListMap!=null) {
selectListMap.forEach(
// 第几列校验(0开始)key 数据源数组value
(key, value) -> {
if(value.length>0) {
CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(2, 65535, key, key);
DataValidationHelper helper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = helper.createExplicitListConstraint(value);
DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
//处理Excel兼容性问题
if (dataValidation instanceof XSSFDataValidation) {
dataValidation.setSuppressDropDownArrow(true);
dataValidation.setShowErrorBox(true);
} else {
dataValidation.setSuppressDropDownArrow(false);
}
dataValidation.setEmptyCellAllowed(true);
dataValidation.setShowPromptBox(true);
dataValidation.createPromptBox("提示", "只能选择下拉框里面的数据");
sheet.addValidationData(dataValidation);
}
}
);
}
}
作者 | _JenKin
来源 | csdn.net/youzi1394046585/article/details/86670203
评论