Zip4j+easyExcel实现 导出加密压缩包
由于zip4j用法限制,不能够直接使用流的形式进行转换,加密等操作;需要将excel,以及压缩好的文件放在某个位置后,再读取给response才能返回给浏览器。方法如下:
引入依赖
<dependency><groupId>net.lingala.zip4j</groupId><artifactId>zip4j</artifactId><version>1.3.2</version>
</dependency>
线程池配置
@Configuration
@EnableAsync
public class ExcutorConfig {private static final Logger logger = LoggerFactory.getLogger(ExcutorConfig.class);@Value("${yml/properties中配置的参数}")private int corePoolSize;@Value("同上")private int maxPoolSize;@Value("同上")private int keepAliveSeconds;@Value("同上")private int queueCapacity;@Bean("downLoadExecutor")//调用线程时的线程名字public Executor asyncExcelServiceExecutor() {logger.info("...ExecutorConfig...asyncServiceExecutor()...启动[发布任务]线程池...");ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(corePoolSize);executor.setMaxPoolSize(maxPoolSize);executor.setKeepAliveSeconds(keepAliveSeconds);executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());executor.initialize();return executor;}
}
controller前端调用接口
@PostMapping("/exportZip")@ApiOperation(value = "导出压缩包", notes = "导出压缩包")public void exportZip(@RequestBody QueryDto QueryDto, HttpServletResponse response) {exportService.exportzip(QueryDto, response);}
压缩加密主业务
@Overridepublic void exportzip(QueryDto QueryDto, HttpServletResponse response) {ServletOutputStream outputStream = null;InputStream inputStream = null;String path = null;String now = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));try {response.setCharacterEncoding("UTF-8");response.setContentType("application/vnd.zip;charset=UTF-8");response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");response.setHeader("Content-Disposition","attachment; filename=" + new String((now + ".zip").getBytes("UTF-8"), "ISO8859-1"));log.info("---response缓冲区大小:" + response.getBufferSize());response.setBufferSize(60000);log.info("---response缓冲区调整后:" + response.getBufferSize());outputStream = response.getOutputStream();//加闩--两个线程同时执行查询CountDownLatch latch = new CountDownLatch(2);exportAsync.queryTable1(latch, 100, QueryDto);exportAsync.queryTable2(latch, 100, QueryDto);//等待2个线程执行完毕latch.await();log.info("------所有excel打包zip---start------");net.lingala.zip4j.core.ZipFile zip = null;net.lingala.zip4j.io.ZipOutputStream zipOutputStream =new net.lingala.zip4j.io.ZipOutputStream(response.getOutputStream());//获取上一步骤中存有excel的文件夹path = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "/";File file = new File(path);zip =new net.lingala.zip4j.core.ZipFile(path + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + ".zip");//设置加密参数ZipParameters zipParameters = new ZipParameters();zipParameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);zipParameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);zipParameters.setEncryptFiles(true);zipParameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);zipParameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);zipParameters.setPassword("123456");zip.addFolder(file, zipParameters);File fileZip =new File(path + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + ".zip");//获取zip文件输入流,写入response返回inputStream = new FileInputStream(fileZip);int len;byte[] buf = new byte[1024];while ((len = inputStream.read(buf)) != -1) {outputStream.write(buf, 0, len);}} catch (ZipException e) {e.getStackTrace();throw new BizException(ResponseCodeEnum.EXPORT_EXCEL_ZIP_EXCEPTION);} catch (InterruptedException e) {e.getStackTrace();throw new BizException(ResponseCodeEnum.EXPORT_EXCEL_ZIP_EXCEPTION);} catch (IOException e) {e.getStackTrace();throw new BizException(ResponseCodeEnum.EXPORT_EXCEL_ZIP_EXCEPTION);} finally {if (outputStream != null) {try {outputStream.close();} catch (IOException e) {e.printStackTrace();throw new BizException(ResponseCodeEnum.EXPORT_EXCEL_ZIP_EXCEPTION);}}if (inputStream != null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();throw new BizException(ResponseCodeEnum.EXPORT_EXCEL_ZIP_EXCEPTION);}}}//返回浏览器后删除暂存的文件夹和文件deleteDir(path);}
开启线程查询数据
@Async("downLoadExecutor")public void excelZdOperation(CountDownLatch latch, int excelSize, GroupVersionQueryDto versionQueryDto)throws IOException {String currentThreadName = Thread.currentThread().getName();log.info("---线程: 【" + currentThreadName + "】 ---startexcel---");//封装queryWrapper条件,查询数据QueryWrapper<Enrity> queryWrapper = new QueryWrapper<>();queryWrapper .lambda().eq(Enrity::getId, QueryDto.getId()).eq(Enrity::getIsValid, Constants.VALID_YES)Integer count = entityMapper.selectCount(queryWrapper);if (count > 0) {int totalPage = count % excelSize == 0 ? count / excelSize : count / excelSize + 1;for (int i = 0; i < totalPage; i++) {Page<Enrity> page = new Page<>(i + 1, excelSize);IPage<Enrity> entityIPage =entityMapper.selectPage(page, QueryWrapper);List<Enrity> records = entityIPage .getRecords();List<EnrityExportDto> EnrityDtos = enrityMapping.domain2DtoList(records);toExcel(zdOperationDtos,ZdOperationExportDto.class,TableNameEnum.TABLE_NAME1.getMsg() + (i + 1));}}latch.countDown();}
easyExcel生成excel临时文件
private synchronized void toExcel(List data, Class clazz, String excelName) throws IOException {//创建暂存excel文件的文件夹,以当前日期格式命名String path = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "/";File fileAddPath = new File(path);if (!fileAddPath.exists()) {fileAddPath.mkdirs();}//通过easyExcel生成xlsx文件,并暂存File excel = new File(path + excelName + ".xlsx");String sheetName1 = "sheet1";ExcelWriter writer = EasyExcel.write(excel, clazz).build();WriteSheet writeSheet = EasyExcel.writerSheet(sheetName1).build();//导出excelwriter.write(data, writeSheet);writer.finish();}
删除临时文件夹数据
private void deleteDir(String dirPath) {File file = new File(dirPath);if (file.isFile()) {file.delete(); // 删除文件} else {File[] files = file.listFiles();if (files == null) {file.delete(); // 删除空文件夹} else {for (File f : files) {deleteDir(f.getAbsolutePath()); // 迭代删除非空文件夹}file.delete();}}}
案例中用到的技术点描述:
1.mybatisPlus
2.easyExcel
3.zip
4.mapstruct
5.线程池异步执行
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
