Java导出List集合到txt文件中,SpringBoot整合EasyExcel实现文件导入导出_java

目录准备工作1. 引入pom依赖2. 实现功能Excel文件下载3. 日志实体类4. 接口和具体实现Excel文件导入5. 文件读取配置6. 读取测试7. 附上自定义属性转换器

准备工作

注意:点击查看官网Demo

1. 引入pom依赖com.alibabaeasyexcel

2. 实现功能结合Vue前端,实现浏览器页面直接导出日志文件实现文件的导入

Excel文件下载

3. 日志实体类

实体类里有自定义转换器:用于Java类型数据和Excel类型数据的转换,非常使用。结合注解,可以非常方便的进行Excel文件导出。

/** *

* 操作日志信息 *

* * @author horse * @since 2020-09-08 * 注意: 实体类中如果使用@Accessory(chain=true),那么导入的数据无法填充到实例中,导出数据不受影响 */@Data@EqualsAndHashCode(callSuper = false)@TableName("tb_operational_log")@ApiModel(value = "OperationalLog对象", description = "操作日志信息")public class OperationalLog implements Serializable {private static final long serialVersionUID = 1L;@ExcelProperty({"操作日志", "日志ID"})@ApiModelProperty(value = "日志ID")@TableId(value = "id", type = IdType.ASSIGN_ID)private String id;@ExcelProperty({"操作日志", "操作类型"})@ApiModelProperty(value = "操作类型")private String operType;@ExcelProperty({"操作日志", "操作描述"})@ApiModelProperty(value = "操作描述")private String operDesc;@ExcelProperty({"操作日志", "操作员ID"})@ApiModelProperty(value = "操作员ID")private String operUserId;@ExcelProperty({"操作日志", "操作员名称"})@ApiModelProperty(value = "操作员名称")private String operUserName;@ExcelProperty({"操作日志", "操作方法"})@ApiModelProperty(value = "操作方法")private String operMethod;@ExcelProperty({"操作日志", "请求方法"})@ApiModelProperty(value = "请求方法")private String operRequWay;@ExcelProperty(value = {"操作日志", "请求耗时:单位-ms"}, converter = CustomRequestTimeConverter.class)@ApiModelProperty(value = "请求耗时:单位-ms")private Long operRequTime;@ExcelProperty({"操作日志", "请求参数"})@ApiModelProperty(value = "请求参数")private String operRequParams;@ExcelProperty({"操作日志", "请求Body"})@ApiModelProperty(value = "请求Body")private String operRequBody;@ExcelProperty({"操作日志", "请求IP"})@ApiModelProperty(value = "请求IP")private String operRequIp;@ExcelProperty({"操作日志", "请求URL"})@ApiModelProperty(value = "请求URL")private String operRequUrl;@ExcelProperty(value = {"操作日志", "日志标识"}, converter = CustomLogFlagConverter.class)@ApiModelProperty(value = "日志标识: 1-admin,0-portal")private Boolean logFlag;@ExcelProperty({"操作日志", "操作状态"})@ApiModelProperty(value = "操作状态:1-成功,0-失败")@TableField(value = "is_success")private Boolean success;@ExcelIgnore@ApiModelProperty(value = "逻辑删除 1-未删除, 0-删除")@TableField(value = "is_deleted")@TableLogic(value = "1", delval = "0")private Boolean deleted;@ExcelProperty(value = {"操作日志", "创建时间"}, converter = CustomTimeFormatConverter.class)@ApiModelProperty(value = "创建时间")private Date gmtCreate;}

4. 接口和具体实现

4.1 接口

@OperatingLog(operType = BlogConstants.EXPORT, operDesc = "导出操作日志,写出到响应流中")@ApiOperation(value = "导出操作日志", hidden = true)@PostMapping("/oper/export")public void operLogExport(@RequestBody List logIds, HttpServletResponse response) {operationalLogService.operLogExport(logIds, response);}

4.2 具体实现

自定义导出策略HorizontalCellStyleStrategy自定义导出拦截器CellWriteHandler,更加精确的自定义导出策略/** * 导出操作日志(可以考虑分页导出) * * @param logIds * @param response */@Overridepublic void operLogExport(List logIds, HttpServletResponse response) {OutputStream outputStream = null;try {List operationalLogs;LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper().orderByDesc(OperationalLog::getGmtCreate);// 如果logIds不为null,按照id查询信息,否则查询全部if (!CollectionUtils.isEmpty(logIds)) {operationalLogs = this.listByIds(logIds);} else {operationalLogs = this.list(queryWrapper);}outputStream = response.getOutputStream();// 获取单元格样式HorizontalCellStyleStrategy strategy = MyCellStyleStrategy.getHorizontalCellStyleStrategy();// 写入响应输出流数据EasyExcel.write(outputStream, OperationalLog.class).excelType(ExcelTypeEnum.XLSX).sheet("操作信息日志")// .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 自适应列宽(不是很适应,效果并不佳).registerWriteHandler(strategy) // 注册上面设置的格式策略.registerWriteHandler(new CustomCellWriteHandler()) // 设置自定义格式策略.doWrite(operationalLogs);} catch (Exception e) {log.error(ExceptionUtils.getMessage(e));throw new BlogException(ResultCodeEnum.EXCEL_DATA_EXPORT_ERROR);} finally {IoUtil.close(outputStream);}}

自定义导出策略简单如下:

/** * @author Mr.Horse * @version 1.0 * @description: 单元格样式策略 * @date 2021/4/30 8:43 */public class MyCellStyleStrategy {/** * 设置单元格样式(仅用于测试) * * @return 样式策略 */public static HorizontalCellStyleStrategy getHorizontalCellStyleStrategy() {// 表头策略WriteCellStyle headerCellStyle = new WriteCellStyle();// 表头水平对齐居中headerCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 背景色headerCellStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());WriteFont headerFont = new WriteFont();headerFont.setFontHeightInPoints((short) 14);headerCellStyle.setWriteFont(headerFont);// 自动换行headerCellStyle.setWrapped(Boolean.FALSE);// 内容策略WriteCellStyle contentCellStyle = new WriteCellStyle();// 设置数据允许的数据格式,这里49代表所有可以都允许设置contentCellStyle.setDataFormat((short) 49);// 设置背景色: 需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定contentCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);contentCellStyle.setFillForegroundColor(IndexedColors.GREY_40_PERCENT.getIndex());// 设置内容靠左对齐contentCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);// 设置字体WriteFont contentFont = new WriteFont();contentFont.setFontHeightInPoints((short) 12);contentCellStyle.setWriteFont(contentFont);// 设置自动换行contentCellStyle.setWrapped(Boolean.FALSE);// 设置边框样式和颜色contentCellStyle.setBorderLeft(MEDIUM);contentCellStyle.setBorderTop(MEDIUM);contentCellStyle.setBorderRight(MEDIUM);contentCellStyle.setBorderBottom(MEDIUM);contentCellStyle.setTopBorderColor(IndexedColors.RED.getIndex());contentCellStyle.setBottomBorderColor(IndexedColors.GREEN.getIndex());contentCellStyle.setLeftBorderColor(IndexedColors.YELLOW.getIndex());contentCellStyle.setRightBorderColor(IndexedColors.ORANGE.getIndex());// 将格式加入单元格样式策略return new HorizontalCellStyleStrategy(headerCellStyle, contentCellStyle);}}

自定义导出拦截器简单如下:

/** * @author Mr.Horse * @version 1.0 * @description 实现CellWriteHandler接口, 实现对单元格样式的精确控制 * @date 2021/4/29 21:11 */public class CustomCellWriteHandler implements CellWriteHandler {private static Logger logger = LoggerFactory.getLogger(CustomCellWriteHandler.class);@Overridepublic void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {}/** * 单元格创建之后(没有写入值) * * @param writeSheetHolder * @param writeTableHolder * @param cell * @param head * @param relativeRowIndex * @param isHead */@Overridepublic void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell,Head head, Integer relativeRowIndex, Boolean isHead) {}@Overridepublic void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {}/** * 单元格处理后(已写入值): 设置第一行第一列的头超链接到EasyExcel的官网(本系统的导出的excel 0,1两行都是头,所以只设置第一行的超链接) * 这里再进行拦截的单元格样式设置的话,前面该样式将全部失效 * * @param writeSheetHolder * @param writeTableHolder * @param cellDataList * @param cell * @param head * @param relativeRowIndex * @param isHead */@Overridepublic void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {// 设置超链接if (isHead && cell.getRowIndex() == 0 && cell.getColumnIndex() == 0) {logger.info(" ==> 第{}行,第{}列超链接设置完成", cell.getRowIndex(), cell.getColumnIndex());CreationHelper helper = writeSheetHolder.getSheet().getWorkbook().getCreationHelper();Hyperlink hyperlink = helper.createHyperlink(HyperlinkType.URL);hyperlink.setAddress("https://github.com/alibaba/easyexcel");cell.setHyperlink(hyperlink);}// 精确设置单元格格式boolean bool = isHead && cell.getRowIndex() == 1 &&(cell.getStringCellValue().equals("请求参数") || cell.getStringCellValue().equals("请求Body"));if (bool) {logger.info("第{}行,第{}列单元格样式设置完成。", cell.getRowIndex(), cell.getColumnIndex());// 获取工作簿Workbook workbook = writeSheetHolder.getSheet().getWorkbook();CellStyle cellStyle = workbook.createCellStyle();Font cellFont = workbook.createFont();cellFont.setBold(Boolean.TRUE);cellFont.setFontHeightInPoints((short) 14);cellFont.setColor(IndexedColors.SEA_GREEN.getIndex());cellStyle.setFont(cellFont);cell.setCellStyle(cellStyle);}}}

4.3 前端请求

前端在基于Vue+Element的基础上实现了点击导出按钮,在浏览器页面进行下载。

// 批量导出batchExport() {// 遍历获取id集合列表const logIds = []this.multipleSelection.forEach(item => {logIds.push(item.id)}) // 请求后端接口axios({url: this.BASE_API + '/admin/blog/log/oper/export',method: 'post',data: logIds,responseType: 'arraybuffer',headers: { 'token': getToken() }}).then(response => {// type类型可以设置为文本类型,这里是新版excel类型const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;' })const pdfUrl = window.URL.createObjectURL(blob)const fileName = 'HorseBlog操作日志' // 下载文件的名字// 对于标签,只有 Firefox 和 Chrome(内核)支持 download 属性if ('download' in document.createElement('a')) {const link = document.createElement('a')link.href = pdfUrllink.setAttribute('download', fileName)document.body.appendChild(link)link.click()window.URL.revokeObjectURL(pdfUrl) // 释放URL 对象} else {// IE 浏览器兼容方法window.navigator.msSaveBlob(blob, fileName)}})}

测试结果:还行,基本实现了页面下载的功能

Excel文件导入

5. 文件读取配置

本配置基于泛型的方式编写,可扩展性较强。

/** * @author Mr.Horse * @version 1.0 * @description: EasyExcel文件读取配置(不能让spring管理) * @date 2021/4/27 13:24 */public class MyExcelImportConfig extends AnalysisEventListener {private static Logger logger = LoggerFactory.getLogger(MyExcelImportConfig.class);/** * 每次读取的最大数据条数 */private static final int MAX_BATCH_COUNT = 10;/** * 泛型bean属性 */private T dynamicService;/** * 可接收任何参数的泛型List集合 */List list = new ArrayList();/** * 构造函数注入bean(根据传入的bean动态注入) * * @param dynamicService */public MyExcelImportConfig(T dynamicService) {this.dynamicService = dynamicService;}/** * 解析每条数据都进行调用 * * @param data * @param context */@Overridepublic void invoke(T data, AnalysisContext context) {logger.info(" ==> 解析一条数据: {}", JacksonUtils.objToString(data));list.add(data);if (list.size() > MAX_BATCH_COUNT) {// 保存数据saveData();// 清空listlist.clear();}}/** * 所有数据解析完成后,会来调用一次 * 作用: 避免最后集合中小于 MAX_BATCH_COUNT 条的数据没有被保存 * * @param context */@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {saveData();logger.info(" ==> 数据解析完成数据保存开始: {}", list.size());list.forEach(System.out::println);logger.info(" ==> 数据保存结束数据解析失败,但是继续读取下一行:{}", exception.getMessage());//如果是某一个单元格的转换异常 能获取到具体行号if (exception instanceof ExcelDataConvertException) {ExcelDataConvertException convertException = (ExcelDataConvertException) exception;logger.error("第{}行,第{}列数据解析异常", convertException.getRowIndex(), convertException.getColumnIndex());}}}

6. 读取测试@ApiOperation(value = "数据导入测试", notes = "操作日志导入测试[OperationalLog]", hidden = true)@PostMapping("/import")public R excelImport(@RequestParam("file") MultipartFile file) throws IOException {EasyExcel.read(file.getInputStream(), OperationalLog.class, new MyExcelImportConfig(operationalLogService)).sheet().doRead();return R.ok().message("文件导入成功");}

7. 附上自定义属性转换器

转换器的属性内容转换,需要根据自己的实际业务需求而定,这里仅作为简单示例

/** * @author Mr.Horse * @version 1.0 * @description: 自定义excel转换器: 将操作日志的请求耗时加上单位 "ms" * @date 2021/4/27 10:25 */public class CustomRequestTimeConverter implements Converter {/** * 读取数据时: 属性对应的java数据类型 * * @return */@Overridepublic Class supportJavaTypeKey() {return Long.class;}/** * 写入数据时: excel内部的数据类型,因为请求耗时是long类型,对应excel是NUMBER类型,但是加上"ms后对应的是STRING类型" * * @return */@Overridepublic CellDataTypeEnum supportExcelTypeKey() {return CellDataTypeEnum.STRING;}/** * 读取回调 * * @param cellData * @param contentProperty * @param globalConfiguration * @return * @throws Exception */@Overridepublic Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {// 截取字符串: "ms",转换为long类型String value = cellData.getStringValue();return Long.valueOf(value.substring(0, value.length() - 2));}@Overridepublic CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {// 添加字符串: "ms"return new CellData(String.valueOf(value).concat("ms"));}}

格式化时间

/** * @author Mr.Horse * @version 1.0 * @description: {description} * @date 2021/4/27 14:01 */public class CustomTimeFormatConverter implements Converter {@Overridepublic Class supportJavaTypeKey() {return Date.class;}@Overridepublic CellDataTypeEnum supportExcelTypeKey() {return CellDataTypeEnum.STRING;}@Overridepublic Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {String value = cellData.getStringValue();return DateUtil.parse(value, DatePattern.NORM_DATETIME_PATTERN);}@Overridepublic CellData convertToExcelData(Date value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {return new CellData(DateUtil.format(value, DatePattern.NORM_DATETIME_PATTERN));}}

EasyExcel简单使用,到此结束,打完收功。

以上就是SpringBoot整合EasyExcel实现文件导入导出的详细内容,更多关于SpringBoot整合EasyExcel的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:SpringBoot+easypoi实现数据的Excel导出Springboot实现导入导出Excel的方法SpringBoot内存数据导出成Excel的实现方法SpringBoot 导出数据生成excel文件返回方式SpringBoot中EasyExcel实现Excel文件的导入导出Springboot使用POI实现导出Excel文件示例SpringBoot+EasyPoi实现excel导出功能
windows 批处理把所有java源码导入一个txt文件中如何将java的输出保存到文件中作为程序日志-百度经验java导出文件放到压缩包里_陈书予的博客-CSDN博客java的io操作(将字符串写入到txt文件中)_java_脚本之家Java 8中集合优雅快速的处理方式 - 云+社区 - 腾讯云Java集合--List - 简书Java 序列化 | 菜鸟教程 - runoob.comjava实现导入导出excel数据 - 简书SpringBoot整合EasyExcel实现文件导入导出_java_脚本之家java导出PDFjava通过poi导出excel文件到浏览器直接下载Spring mvc+maven+java 导出Excel表格+读取Excel并输出listjava导出多个excel文件并以压缩包的形式下载Java导出一百万数据Exceljava导出excel的两种方式Java导出数据Excel导出TXT文件List<Map<String,Object>> 类型数据导出到Excel文件Java导出excel文件以.xlsx后缀结尾,可设置部分单元格只读java实现导出excel表磁盘上(三)---完整封装,可直接使用javaList导出exceljava小算法介绍-合并List中满足某些字段相同的记录java实现导出csv文件+图片压缩成zip格式springboot框架-java实现Excel、csv、txt 文件的批量导出数据-亲手实测(二)-csv & txtjava导出excel包含图片java poi 导出excel 导出文本文件 工具类(以流的方式)Java后台代码实现POI文件的导入导出JAVA使用POI导出图片ExcelJava导出CSV文件(分页查询大数据量)Java工具类 将List集合对象生成Excel数据表格CreateExcelUtiljava百万条数据导出到excel表格Java导出Excel模板Java中导出数据Excel处理方法使用java在后台将数据导出为excel文件Java实现文件批量导入导出实例(兼容xls,xlsx)Java将数据导出到Excel文件中mongoDB导出数据库所有集合内容json文件Java-导出数据post方式
脱颖而出和出类拔萃的区别王玉芳紫砂壶艺术欣赏竹华里竹苑小区湾里二手房房价走势自动挡上坡起步技巧半坡起步技巧图解金主的绯闻娇妻金漾清月作品孤独的梦想家豆瓣姓景两个字洋气点的宝宝名字请问福州哪家医院的皮肤科比较好大学规划大一到大四大学四年规划简短电子邀请函免费制作电子请帖模板免费春节的英语电子邀请函益美得CT中神盾SWS蒜头王八是啥意思lv怎么查询是否是正品干部作风担当作为大师注射器作画被讽刺很想感叹一下郑爽苏利股份