exceljava导出「java如何导出」
日常在做后台系统,经常会很频繁的遇到Excel导入导出问题,正好这次在做一个电商管理的后台系统,就想着造一个公用工具的轮子,来进行Excel的导入导出。
一般我们在导出Excel做法是:前端用户导出的前端表格,而前端表格同时对应后台有一个映射类。
先理一下需要实现的效果:
1、导出方法接收一个list集合,和一个Class类型,
2、HttpServletResponse 对象导出是可能会有下拉列表,所以需要一个map存储下拉列表数据源
3、传入参数后只需一行代码即可导出导入方法需要传入File文件,以及一个Class类型,导入之后将会返回一个list集合,里面的对象就是传入类型的对象,
4、工具类传入参数后只需一行代码即可导入
实现过程:
首先需要创建三个注解一个是EnableExport ,必须有这个注解才能导出
/** * 设置允许导出 */@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface EnableExport { String fileName();}@EnableExportField,有这个注解的字段才会导出到Excel里面,并且可以设置列宽。
/** * 设置该字段允许导出 * 并且可以设置宽度 */@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface EnableExportField { int colWidth() default 100; String colName();}
再就是@ImportIndex,导入的时候设置Excel中的列对应的序号
/** * 导入时索引 */@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface ImportIndex { int index() ;}注解使用示例
三个注解创建好之后就开始操作Excel了导入方法。在后台接收到前端上传的Excel文件之后,使用poi来读取Excel文件。
我们根据传入的类型上面的字段注解的顺序来分别为不同的字段赋值,然后存入集合中,再返回
代码如下:
/** * 将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;}接下来开始导出方法。
导出分为几个步骤:
第一步:建立一个工作簿,也就是类型新建一个Excel文件
第二步:建立一张sheet表
第三步:设置标的行高和列宽
第四步:绘制标题和表头
这两个方法是自定义方法,代码会贴在后面
第五步:写入数据到Excel
第六步:创建下拉列表
第七步:写入文件到response
到这里导出工作就完成了下面是一些自定义方法的代码/** * 获取一个基本的带边框的单元格 * @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); } } ); }}
使用实例
导出数据导入数据(返回对象List)同学们,你们觉得这样的导出方式优雅吗?本人花费2个月时间,整理了一套java开发技术资料,内容涵盖java基础,分布式、微服务等主流技术资料,包含大厂面经,学习笔记、源码讲义、项目实战、讲解视频。
java面试资料
希望可以帮助一些想通过自学提升能力的朋友,领取资料,扫码关注一下
记得转发 关注 私信
私信回复【2022面试资料】
领取更多学习资料
相关文章
- 创享互动平台「纯会员制社交电商」
- 微服务开发实战「微服务架构设计」
- 使用本地缓存中的常见问题「缓存不一致解决方案」
- 农村电商怎么运营「乡间小事」
- 旅游产品在线营销分析「在线旅游市场度假发展数据」
- 美工要如何提升自身的技能才能月薪过万「美工学徒第一个月1000」
- 你不必假装自己很合群「不需要刻意合群有趣的人」
- 厦门代运营淘宝公司「知乎落地厦门」
- 创天下与仟亿资本正式达成战略合作了吗「创世伙伴资本」
- 临沧轻享优品贸易有限公司「临沧公众号」
- 000762西藏矿业股「西藏矿业(000762.SZ)要嗨了」
- 携程的发展对于旅游接待业而言有何启发「春秋旅行社盈利模式」
- 福建省消委会约谈7家电商平台并督促整改工作「福建消费网」
- 淘宝关于产品拍照建议怎么写「如何拍网店产品照片」
- 进博会浙江交易团「浙江京剧团」
- 饼干拍摄技巧「面包摄影」
- 外卖骑手的发展和保障饿了么和美团都是怎么做的「饿了么外卖骑手攻略」
- 如何学好美工基础,难不难学「如何避免少走弯路高效学习美工设计」