常用开发功能——批量文件导出

文章介绍了如何处理批量导出场站订单信息的需求。通过在内存中生成Excel文件,然后将它们添加到一个压缩文件中,最后以.zip格式返回。主要步骤包括设置响应头为application/zip,循环遍历场站ID,为每个场站生成Excel,写入ZipOutputStream,并使用EasyExcel进行数据到Excel的转换。
摘要由CSDN通过智能技术生成

        某天工作接到一个需求:批量导出场站的订单信息,一个场站一个Excel文档;

        与单个文件导出的区别在于,单个导出一次性只导出一个文件,在输出流中写入这一个文件即可,那么如何一次性导出多个文件?难道一次接口返回能被循环读取重复打开保存对话框?

        不是,其实是使用压缩文件,在内存中将生成的EXCEL文件依次加入到压缩文件中,最后形成一个.zip格式的文件,写入输出流作为接口的返回;

理解简单,话不多说,代码如下:

	public void exportLogBatch(ChargingParkCouponLogVO chargingParkCouponLog, HttpServletResponse response) throws IOException {
		// 设置响应头,指定下载的文件类型为压缩文件
		response.setContentType("application/zip");
		String start = DateUtil.format(chargingParkCouponLog.getStartDate(), "yyyy-MM-dd");
		String end = DateUtil.format(chargingParkCouponLog.getEndDate(), "yyyy-MM-dd");
		response.setHeader("Content-Disposition", "attachment; filename=\"订单停车券按场站批量导出(" + start + "~" + end + ").zip\"");
		String[] parkIdArr = chargingParkCouponLog.getParkIds().split(",");
		try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
			for (String s : parkIdArr) {
				try {
					ChargingParkConfig chargingParkConfig = chargingParkConfigService.getById(Long.valueOf(s));
					if (ObjectUtils.isEmpty(chargingParkConfig)) {
						continue;
					}
					List<ChargingParkCouponLogExport> exportList = generateExportFiles(chargingParkCouponLog);
					byte[] bytes = generateFileBytes(exportList);
					ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
					// 创建压缩文件的条目,并将文件内容写入压缩文件
					ZipEntry zipEntry = new ZipEntry("道闸发券识别异常清单—" + chargingParkConfig.getParkName() + ".xlsx");
					zipOut.putNextEntry(zipEntry);

					byte[] buffer = new byte[1024];
					int length;
					while ((length = byteArrayInputStream.read(buffer)) >= 0) {
						zipOut.write(buffer, 0, length);
					}
					zipOut.closeEntry();
				} catch (Exception e) {
					throw new ServiceException("停车券发放记录列表导出异常,编号:" + s);
				}
			}
			zipOut.finish();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private List<ChargingParkCouponLogExport> generateExportFiles(ChargingParkCouponLogVO chargingParkCouponLog) {
		Page page = new Page<>();
		page.setSize(10000L);
		List list = chargingParkCouponLogService.selectChargingParkCouponLogPage(page, chargingParkCouponLog).getRecords();
		List<ChargingParkCouponLogExport> exportList = new LinkedList<>();
		list.forEach(item -> {
			ChargingParkCouponLogExport logExport = new ChargingParkCouponLogExport();
			BeanUtils.copyProperties(item, logExport);
			exportList.add(logExport);
		});
		return exportList;
	}

	private byte[] generateFileBytes(List<ChargingParkCouponLogExport> exportList) {
		// 创建一个ByteArrayOutputStream对象,用于将Excel数据写入内存中的字节数组
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

		// 使用ExcelWriter创建一个写入器,并将其与ByteArrayOutputStream关联
		ExcelWriter excelWriter = EasyExcel.write(outputStream, ChargingParkCouponLogExport.class).build();

		// 创建一个WriteSheet对象,设置Sheet名称和表头类
		WriteSheet writeSheet = EasyExcel.writerSheet().build();

		// 将数据列表写入Excel文件
		excelWriter.write(exportList, writeSheet);

		// 关闭ExcelWriter
		excelWriter.finish();

		// 获取ByteArrayOutputStream的字节数组
		byte[] bytes = outputStream.toByteArray();

		return bytes;
	}

调用接口:

 

返回结果:

总结下导出逻辑的变更:

         之前:准备要导出的场站ID,获取该场站要导出的数据,调用导出工具类写输出流;

         之后:准备要导出的场站的批量的ID列表,遍历ID列表循环获取场站各自要导出的数据,打开请求的总输出流作为ZipOutStream的输入流,对每个要导出的场站列表,创建单独的二进制输出流,将各自要导出的数据,写入输出流中,写入完后将输出流返回为二进制数组,作为输入流,写入创建的压缩文件中,将所有的导出文件二进制数据都写入各自的ZipEntry,最后写入总的ZipOutStream,循环执行,即可导出所有的文件作为压缩包;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值