java批量文件打包成压缩成zip下载和大量数据导出excel时的处理方法_java 导出多文件数据并打成zip报 优化时间方案


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@SuppressWarnings("restriction")
public class FileDownloadUtils {

    private static final Logger logger = LoggerFactory.getLogger(FileDownloadUtils.class);

    /\*\*
 \* 编译下载的文件名
 \* @param filename
 \* @param agent
 \* @return
 \* @throws IOException
 \*/
    public static String encodeDownloadFilename(String filename, String agent)throws IOException {
        if (agent.contains("Firefox")) { // 火狐浏览器
            filename = "=?UTF-8?B?"
                    + new BASE64Encoder().encode(filename.getBytes("utf-8"))
                    + "?=";
            filename = filename.replaceAll("\r\n", "");
        } else { // IE及其他浏览器
            filename = URLEncoder.encode(filename, "utf-8");
            filename = filename.replace("+"," ");
        }
        return filename;
    }

    /\*\*
 \* 创建文件夹;
 \* @param path
 \*/
    public static void createFile(String path) {
        File file = new File(path);
        //判断文件是否存在;
        if (!file.exists()) {
            //创建文件;
            file.mkdirs();
        }
    }

    /\*\*
 \* 生成.zip文件;
 \* @param path
 \* @throws IOException
 \*/
    public static ZipOutputStream craeteZipPath(String path) throws IOException{
        ZipOutputStream zipOutputStream = null;
        File file = new File(path+DateUtils.getDateWx()+".zip");
        zipOutputStream = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
        File[] files = new File(path).listFiles();
        FileInputStream fileInputStream = null;
        byte[] buf = new byte[1024];
        int len = 0;
        if(files!=null && files.length > 0){
            for(File excelFile:files){
                String fileName = excelFile.getName();
                fileInputStream = new FileInputStream(excelFile);
                //放入压缩zip包中;
                zipOutputStream.putNextEntry(new ZipEntry(path + "/"+fileName));
                //读取文件;
                while((len=fileInputStream.read(buf)) >0){
                    zipOutputStream.write(buf, 0, len);
                }
                //关闭;
                zipOutputStream.closeEntry();
                if(fileInputStream != null){
                    fileInputStream.close();
                }
            }
        }

        /\*if(zipOutputStream !=null){
 zipOutputStream.close();
 }\*/
        return zipOutputStream;
    }


    /\*\*
 \* //压缩文件
 \* @param srcfile 要压缩的文件数组
 \* @param zipfile 生成的zip文件对象
 \*/
    public static void ZipFiles(java.io.File[] srcfile, File zipfile) throws Exception {
        byte[] buf = new byte[1024];
        FileOutputStream fos = new FileOutputStream(zipfile);
        ZipOutputStream out = new ZipOutputStream(fos);
        for (int i = 0; i < srcfile.length; i++) {
            FileInputStream in = new FileInputStream(srcfile[i]);
            out.putNextEntry(new ZipEntry(srcfile[i].getName()));
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            out.closeEntry();
            in.close();
        }
        out.close();
        fos.flush();
        fos.close();
    }

    /\*\*
 \* 删除文件夹及文件夹下所有文件
 \* @param dir
 \* @return
 \*/
    public static boolean deleteDir(File dir) {
        if (dir == null || !dir.exists()){
            return true;
        }
        if (dir.isDirectory()) {
            String[] children = dir.list();
            //递归删除目录中的子目录下
            for (int i=0; i<children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空,可以删除
        return dir.delete();
    }

    /\*\*
 \* 生成html
 \* @param msg
 \* @return
 \* @author zgd
 \* @time 2018年6月25日11:47:07
 \*/
    public static String getErrorHtml(String msg) {
        StringBuffer sb = new StringBuffer();
        sb.append("<html>");
        sb.append("<head>");
        sb.append("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>");
        sb.append("</head>");
        sb.append("<body>");
        sb.append("<div id='errorInfo'> ");
        sb.append("</div>");
        sb.append("<script>alert('"+msg+"')</script>");
        sb.append("</body>");
        sb.append("</html>");
        return sb.toString();
    }


    /\*\*
 \* 设置下载excel的响应头信息
 \* @param response
 \* @param request
 \* @param agent
 \* @param fileName
 \* @throws IOException
 \* @author zgd
 \* @time 2018年6月25日11:47:07
 \*/
    public static void setExcelHeadInfo(HttpServletResponse response, HttpServletRequest request, String fileName)  {
        try {
            // 获取客户端浏览器的类型
            String agent = request.getHeader("User-Agent");
            // 对文件名重新编码
            String encodingFileName = FileDownloadUtils.encodeDownloadFilename(fileName, agent);
            // 告诉客户端允许断点续传多线程连接下载
            response.setHeader("Accept-Ranges", "bytes");
            //文件后缀
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + encodingFileName);
        } catch (IOException e) {
            logger.error(Thread.currentThread().getStackTrace()[1].getMethodName() +"发生的异常是: ",e);
            throw new RuntimeException(e);
        }
    }

    /\*\*
 \* 设置下载zip的响应头信息
 \* @param response
 \* @param fileName 文件名
 \* @param request
 \* @throws IOException
 \* @author zgd
 \* @time 2018年6月25日11:47:07
 \*/
    public static void setZipDownLoadHeadInfo(HttpServletResponse response, HttpServletRequest request, String fileName) throws IOException {
        // 获取客户端浏览器的类型
        String agent = request.getHeader("User-Agent");
        response.setContentType("application/octet-stream ");
        // 表示不能用浏览器直接打开
        response.setHeader("Connection", "close");
        // 告诉客户端允许断点续传多线程连接下载
        response.setHeader("Accept-Ranges", "bytes");
        // 对文件名重新编码
        String encodingFileName = FileDownloadUtils.encodeDownloadFilename(fileName, agent);
        response.setHeader("Content-Disposition", "attachment; filename=" + encodingFileName);
    }

}

1.控制层接收参数
/\*\*
 \* 导出商家订单数据列表的excel文件
 \*
 \* @param request
 \* @author zgd
 \* @time 2018年6月5日14:47:21
 \*/
    @RequestMapping(value = "/exportStoreOrderList")
    public void exportStoreOrderList(HttpServletRequest request, HttpServletResponse response) {
       /\*
 \* 从service层获取List的数据,此处省略
 \*/
        List<Map<String, Object>> list = data;

        //导出excel
        // 创建Excel文件,每个excel限制10000条数据,超过则打包zip
        int size = 10000;
        //每次缓存1000条到内存,其余写到磁盘
        int rowCache = 1000;
        String fileName = "商家订单数据-" + DateUtils.getDateWx();
        // 创建Excel文件,每个excel限制10000条数据,超过则打包zip
        int size = 10000;
        //每次缓存1000条到内存,其余写到磁盘
        int rowCache = 1000;
        String fileName = "商家订单数据-" + DateUtils.getDateWx();
        //导出excel
        try {
            //excel文件个数
            int n = list.size() / size + 1;
            if (list != null) {
                SXSSFWorkbook workbook = getStoreOrderExcel(list, rowCache);
                if (n == 1) {
                    //下载单个excle
                    fileName = fileName + ".xls";
                    FileDownloadUtils.downloadExcel(request, response, fileName, workbook);
                } else {
                    fileName = "批量" + fileName + ".zip";
                    String realPath = request.getSession().getServletContext().getRealPath("WEB-INF");
                    //创建临时文件夹保存excel
                    String tempDir = realPath + "/tempDir/" + DateUtils.getDateWx();
                    List<File> files = getStoreOrderExcels(tempDir, size, list, rowCache);
                    String zipPath = tempDir + "\\" + fileName;
                    //下载zip
                    FileDownloadUtils.downloadZip(request, response, fileName, files, zipPath);
                    //删除tempDir文件夹和其中的excel和zip文件
                    boolean b = FileDownloadUtils.deleteDir(new File(realPath + "\\tempDir"));
                    if (!b) {
                        throw new RuntimeException("tempDir文件夹及其中的临时Excel和zip文件删除失败");
                    }
                }
            }
        }catch (Exception e) {
            try {
                if (!response.isCommitted()) {
                    response.setContentType("text/html;charset=utf-8");
                    response.setHeader("Content-Disposition", "");
                    String html = FileDownloadUtils.getErrorHtml("下载失败");
                    response.getOutputStream().write(html.getBytes("UTF-8"));
                }
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }

2. getStoreOrderExcel方法解析
 /\*\*
 \* 将数据库查出来的商家订单数据,创建成excel
 \* @param list 商家订单数据
 \* @param rowCache 缓冲的行数
 \* @return
 \*/
    private SXSSFWorkbook getStoreOrderExcel(List<Map<String, Object>> list, int rowCache) {
        //如果rowCache是1000,就是每次读取1000条数据到缓存中
         SXSSFWorkbook workbook = new SXSSFWorkbook(rowCache);
         /\*\*
 ....设置行,列,塞入数据
 \*\*/
         return workbook;
    }

2.1 这里分成两条线: 下载excel和下载zip
2.2 下载excel支线
2.2.1 downloadExcel方法解析
/\*\*
 \* 下载excel
 \*
 \* @param request
 \* @param response
 \* @param fileName
 \* @param workbook
 \* @throws Exception
 \* @author zgd
 \* @time 2018年6月25日11:47:07
 \*/
    private void downloadExcel(HttpServletRequest request, HttpServletResponse response, String fileName, SXSSFWorkbook workbook) {
        //一个流两个头
        //设置下载excel的头信息
        FileDownloadUtils.setExcelHeadInfo(response, request, fileName);

        // 写出文件
        ServletOutputStream os = null;
        try {
            os = response.getOutputStream();
            workbook.write(os);
        } catch (IOException e) {
            logger.error(Thread.currentThread().getStackTrace()[1].getMethodName() + "发生的异常是: ", e);
            throw new RuntimeException(e);
        } finally {
            try {
                if (os != null) {
                    os.flush();


![img](https://img-blog.csdnimg.cn/img_convert/3aeb752d1a3b307520e6f168816449c5.png)
![img](https://img-blog.csdnimg.cn/img_convert/fa6792eab841799dc9f9ba8095f05ccd.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

               os.flush();


[外链图片转存中...(img-A9CBmWCp-1714704140903)]
[外链图片转存中...(img-7yhtOP89-1714704140903)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Java可以使用POI库来进行Word文档的操作,ZipFile类来进行压缩文件的操作。具体步骤如下: 1. 首先,将要导出数据存储到一个List中。 2. 使用POI库来创建一个新的Word文档,并将List中的每一条数据依次插入到Word文档中,形一个单独的Word文档。 3. 将每个单独的Word文档保存为.doc或.docx格式的文件。 4. 使用ZipFile类将所有的Word文档压缩成一个.zip文件。 5. 把.zip文件发送给需要的人或存储到指定的位置。 这个过程需要使用到Java的IO操作,例如FileInputStream、FileOutputStream、ZipOutputStream等类来实现,还需要学习Java的POI和ZipFile类的使用方法。总体来说,这个过程需要一定的Java编程基础,但是学起来并不难,只要按照步骤一步一步来,就可以完这个导出数据的过程。 ### 回答2: Java可以使用Apache POI库来实现数据导出为Word文档。使用POI库可以创建Word文档、给文档添加表格、样式、图片、超链接等内容,并且可以将文档保存为doc或docx格式。 要实现将每一条数据导出为单独的Word文档,可以使用循环和条件语句来遍历数据,并通过POI库将数据添加到新建的Word文档中,最后保存为单独的文档。要将这些单独的Word文档压缩成一个ZIP文件,可以使用JavaZipOutputStream类,该类可以将多个文件压缩成一个ZIP文件。 具体实现中,首先要引入POI库和ZipOutputStream类所需要的依赖,然后通过循环遍历数据,将每一条数据添加到新建的Word文档中,并保存为单独的Word文件。最后,将这些单独的Word文件通过ZipOutputStream类压缩成一个ZIP文件实现的代码可以参考以下示例: ``` import java.io.*; import java.util.zip.*; import org.apache.poi.xwpf.usermodel.*; public class WordExport { private final static String FILE_PATH = "data/"; // Word文件保存路径 private final static String ZIP_FILE_NAME = "data.zip"; // 压缩后的ZIP文件名 public static void main(String[] args) throws IOException { // 待导出数据 String[] data = {"数据1", "数据2", "数据3"}; // 创建ZipOutputStream对象 ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(FILE_PATH + ZIP_FILE_NAME)); // 遍历数据,将每个数据导出为单独的Word文件,并压缩ZIP文件中 for (int i = 0; i < data.length; i++) { // 新建Word文档 XWPFDocument document = new XWPFDocument(); // 添加数据到文档中 XWPFParagraph paragraph = document.createParagraph(); XWPFRun run = paragraph.createRun(); run.setText(data[i]); // 保存Word文档 FileOutputStream fos = new FileOutputStream(FILE_PATH + "data" + (i + 1) + ".docx"); document.write(fos); fos.close(); // 压缩Word文件ZIP文件中 FileInputStream fis = new FileInputStream(FILE_PATH + "data" + (i + 1) + ".docx"); zos.putNextEntry(new ZipEntry("data" + (i + 1) + ".docx")); byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) > 0) { zos.write(buffer, 0, len); } zos.closeEntry(); fis.close(); } // 关闭ZipOutputStream流 zos.close(); } } ``` 上述代码中,首先定义了Word文件保存路径和压缩后的ZIP文件名。然后通过遍历待导出数据,将每个数据添加到新建的Word文档中,并保存为单独的Word文件,在保存Word文件后,将每个Word文件通过ZipOutputStream类压缩ZIP文件中。遍历结束后,关闭ZipOutputStream流,导出压缩过程完。 ### 回答3: Java可以通过Apache POI库来实现数据导出为Word文档的功能,Apache POI库提供了一些API,可以很方便地创建并编辑Word文档。对于将多个Word文档压缩成一个Zip文件的需求,Java可以使用ZipOutputStream类来实现ZipOutputStream类能够很方便地对多个文件进行压缩处理。以下是大致的实现步骤: 1. 使用POI库创建并编辑Word文档,将数据写入到文档中。 2. 每次写完一条数据后就将该文档保存到本地,可以使用doc或docx格式,以便后续进行压缩。 3. 将所有生的Word文档文件名存储到一个List中。 4. 使用ZipOutputStream类创建一个Zip压缩文件,即ZipOutputStream将数据写入到.zip文件中。 5. 遍历保存Word文档文件名的List,并逐个将文件压缩ZipOutputStream中。 6. 关闭ZipOutputStream和每个Word文档的输入流。 代码示例: ```java // 创建一个Zip文件输出流 ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream("output.zip")); // 设置压缩方法 zipOut.setMethod(ZipOutputStream.DEFLATED); // 遍历Word文档文件名的List for (String fileName : fileNames) { // 将Word文档文件读入 FileInputStream fis = new FileInputStream(new File(fileName)); // 将读入的Word文档压缩ZipOutputStream中 zipOut.putNextEntry(new ZipEntry(new File(fileName).getName())); // 读入数据到缓冲区 byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) != -1) { zipOut.write(buffer, 0, len); } // 关闭输入流 fis.close(); // 关闭该Entry zipOut.closeEntry(); } // 关闭ZipOutputStream zipOut.close(); ``` 这样,所有的Word文档都被压缩成了一个Zip文件,每个Word文档都形了一个单独的Entry,并可以使用任何Zip文件处理工具进行解压。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值