Spring Boot 多文件直接打包下载 zip 文件

2,792 阅读1分钟

引言

最近项目里有个需求,从一个日志表里查多条记录,每一条记录写入到一个 txt 文件,然后把多个 txt 打包成 zip 下载。网上找了一些例子,写的都比较繁琐,我这里的场景是只要把每条记录写入 txt 再打包下载即可,所以用了一种极简的实现方式。

核心实现代码

/**
 * 批量下载作业日志
 *
 * @param jobLogIds 作业日志 id 集合
 * @param response  HttpServletResponse
 */
@Override
@Transactional(rollbackFor = Exception.class)
public void downloadJobLogs(List<String> jobLogIds, HttpServletResponse response) {
    // 查询作业日志
    Example example = new Example(UmiJobLog.class);
    example.createCriteria().andIn("id", jobLogIds);
    List<UmiJobLog> umiJobLogs = this.umiJobLogMapper.selectByExample(example);

    String prefix = DateUtil.format(new Date(), "yyyyMMddHHmmss");
    // 构建下载文件名字,中文名或中英文混合会出错,自行搜索解决办法
    String downloadFileName = "JobLog" + prefix + ".zip";
    // 重置 response,设置参数
    response.reset();
    response.setContentType("application/octet-stream");
    response.setHeader("Content-Disposition", "attachment;filename=" + downloadFileName);
    try (ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream())) {
        for (UmiJobLog jobLog : umiJobLogs) {
            // 作业日志记录格式化为字符串
            String jobLogStr = getJobLogStr(jobLog);
            // zip 文件中放入一个条目
            zipOutputStream.putNextEntry(new ZipEntry(jobLog.getTaskName() + ".txt"));
            // 将字符串写入 zip 条目
            zipOutputStream.write(jobLogStr.getBytes("utf-8"));
            // 完成该条目打包
            zipOutputStream.closeEntry();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
    

/**
 * 构建作业日志字符串
 *
 * @param umiJobLog 作业日志对象
 * @return 字符串
 */
private String getJobLogStr(UmiJobLog umiJobLog) {
    final StringBuilder builder = new StringBuilder();
    builder.append("任务名称:" + umiJobLog.getTaskName());
    builder.append(System.getProperty("line.separator"));
    builder.append("任务类型:" + umiJobLog.getEtlType());
    builder.append(System.getProperty("line.separator"));
    builder.append("调度名称:" + umiJobLog.getScheduleName());
    builder.append(System.getProperty("line.separator"));
    builder.append("任务状态:" + umiJobLog.getStatus());
    builder.append(System.getProperty("line.separator"));
    builder.append("任务开始时间:" + DateUtil.format(umiJobLog.getStartTime(), null));
    builder.append(System.getProperty("line.separator"));
    builder.append("任务结束时间:" + DateUtil.format(umiJobLog.getOverTime(), null));
    builder.append(System.getProperty("line.separator"));
    return builder.toString();
}