zoukankan      html  css  js  c++  java
  • 【SpringBoot/MVC】从Oracle下载百万条记录的CSV

    工程下载地址:https://files.cnblogs.com/files/xiandedanteng/CsvDownloadOracle20191110-2.rar

    画面:

    核心代码:

    控制器:

    package com.hy.csvdld.ctrl;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.net.URLDecoder;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.log4j.Logger;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import com.hy.csvdld.service.EmpService;
    import com.hy.csvdld.util.CsvMaker;
    
    @Controller
    public class WebCtrl {
        private static Logger log = Logger.getLogger(WebCtrl.class);
        
        @Autowired
        EmpService empService;
        
        @RequestMapping("/")
        public String index(Model model) {
            log.info("进入index页");
            return "index.html";
        }
        
        @RequestMapping("/downloadTen")
        public void downloadTen(HttpServletResponse res, HttpServletRequest req) throws Exception {
            log.info("Start downloadTen");
            
            SimpleDateFormat dfs = new SimpleDateFormat("yyyyMMddHHmmss");
            Date time = new Date();
            String tStamp = dfs.format(time);
            
            String localFilename = tStamp+".csv";
            String path=req.getSession().getServletContext().getRealPath("/");
            String localFilepath = path+localFilename;
            log.info("准备生成的本地路径文件名="+localFilepath);
    
            res.setContentType("multipart/form-data");
            res.setCharacterEncoding("UTF-8");
            res.setContentType("text/html");
    
            String userAgent = req.getHeader("User-Agent");
            if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
                // IE Core
                localFilename = java.net.URLEncoder.encode(localFilename, "UTF-8");
            } else {
                // Non-IE Core
                localFilename = new String((localFilename).getBytes("UTF-8"), "ISO-8859-1");
            }
            res.setHeader("Content-Disposition", "attachment;fileName=" + localFilename);
    
            localFilepath = URLDecoder.decode(localFilepath, "UTF-8");
            
            File file=new File(localFilepath);
            
            CsvMaker maker=new CsvMaker();
            maker.makeTenCsv(file, empService);
            
            log.info("已经生成文件:"+localFilepath);
            
            FileInputStream instream = new FileInputStream(localFilepath);
            ServletOutputStream outstream = res.getOutputStream();
            int b = 0;
            byte[] buffer = new byte[1024];
            while ((b = instream.read(buffer)) != -1) {
                outstream.write(buffer, 0, b);
            }
            instream.close();
    
            if (outstream != null) {
                outstream.flush();
                outstream.close();
                boolean isDeleted=file.delete();
                if(isDeleted) {
                    log.info("已经删除文件:"+localFilepath);
                }
            }
        }
        
        @RequestMapping("/downloadMany/{count}")
        public void downloadMany(HttpServletResponse res, HttpServletRequest req,@PathVariable String count) throws Exception {
            log.info("Start downloadGeneratedCsvFile");
            
            SimpleDateFormat dfs = new SimpleDateFormat("yyyyMMddHHmmss");
            Date time = new Date();
            String tStamp = dfs.format(time);
            
            String localFilename = tStamp+".csv";
            String path=req.getSession().getServletContext().getRealPath("/");
            String localFilepath = path+localFilename;
            log.info("准备生成的本地路径文件名="+localFilepath);
    
            res.setContentType("multipart/form-data");
            res.setCharacterEncoding("UTF-8");
            res.setContentType("text/html");
    
            String userAgent = req.getHeader("User-Agent");
            if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
                // IE Core
                localFilename = java.net.URLEncoder.encode(localFilename, "UTF-8");
            } else {
                // Non-IE Core
                localFilename = new String((localFilename).getBytes("UTF-8"), "ISO-8859-1");
            }
            res.setHeader("Content-Disposition", "attachment;fileName=" + localFilename);
    
            localFilepath = URLDecoder.decode(localFilepath, "UTF-8");
            
            File file=new File(localFilepath);
            
            CsvMaker mk=new CsvMaker();
            mk.makeManyCsv(file, empService, Integer.parseInt(count));
            
            log.info("已经生成文件:"+localFilepath);
            
            FileInputStream instream = new FileInputStream(localFilepath);
            ServletOutputStream outstream = res.getOutputStream();
            int b = 0;
            byte[] buffer = new byte[1024];
            while ((b = instream.read(buffer)) != -1) {
                outstream.write(buffer, 0, b);
            }
            instream.close();
    
            if (outstream != null) {
                outstream.flush();
                outstream.close();
                boolean isDeleted=file.delete();
                if(isDeleted) {
                    log.info("已经删除文件:"+localFilepath);
                }
            }
        }
        
        @RequestMapping("/downloadPartial/{count}")
        public void downloadPartial(HttpServletResponse res, HttpServletRequest req,@PathVariable String count) throws Exception {
            log.info("Start downloadPartial");
            
            SimpleDateFormat dfs = new SimpleDateFormat("yyyyMMddHHmmss");
            Date time = new Date();
            String tStamp = dfs.format(time);
            
            String localFilename = tStamp+".csv";
            String path=req.getSession().getServletContext().getRealPath("/");
            String localFilepath = path+localFilename;
            log.info("准备生成的本地路径文件名="+localFilepath);
    
            res.setContentType("multipart/form-data");
            res.setCharacterEncoding("UTF-8");
            res.setContentType("text/html");
    
            String userAgent = req.getHeader("User-Agent");
            if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
                // IE Core
                localFilename = java.net.URLEncoder.encode(localFilename, "UTF-8");
            } else {
                // Non-IE Core
                localFilename = new String((localFilename).getBytes("UTF-8"), "ISO-8859-1");
            }
            res.setHeader("Content-Disposition", "attachment;fileName=" + localFilename);
    
            localFilepath = URLDecoder.decode(localFilepath, "UTF-8");
            
            File file=new File(localFilepath);
            
            CsvMaker mk=new CsvMaker();
            mk.makePartialCsv(file, empService, Integer.parseInt(count));
            
            log.info("已经生成文件:"+localFilepath);
            
            FileInputStream instream = new FileInputStream(localFilepath);
            ServletOutputStream outstream = res.getOutputStream();
            int b = 0;
            byte[] buffer = new byte[1024];
            while ((b = instream.read(buffer)) != -1) {
                outstream.write(buffer, 0, b);
            }
            instream.close();
    
            if (outstream != null) {
                outstream.flush();
                outstream.close();
                boolean isDeleted=file.delete();
                if(isDeleted) {
                    log.info("已经删除文件:"+localFilepath);
                }
            }
        }
    }

    CSV生成器:

    package com.hy.csvdld.util;
    
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.List;
    
    import org.apache.log4j.Logger;
    
    import com.hy.csvdld.Entity.Emp;
    import com.hy.csvdld.service.EmpService;
    
    // 用于生成CSV文件
    public class CsvMaker {
        private static Logger log = Logger.getLogger(CsvMaker.class);
        
        public void makeTenCsv(File file, EmpService empService) {
            try {
                List<Emp> emps = empService.selectTenEmp();
    
                FileWriter fileWriter = new FileWriter(file, true);
    
                int index = 0;
                for (Emp emp:emps) {
                    index++;
    
                    String info =""+index+","+ emp.asCsvLine()+ System.getProperty("line.separator");
                    fileWriter.write(info);
                }
    
                fileWriter.flush();
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        public void makeManyCsv(File file, EmpService empService,int count) {
            try {
                List<Emp> emps = empService.selectMany(count);
    
                FileWriter fileWriter = new FileWriter(file, true);
    
                int index = 0;
                for (Emp emp:emps) {
                    index++;
    
                    String info =""+index+","+ emp.asCsvLine()+ System.getProperty("line.separator");
                    fileWriter.write(info);
                }
    
                fileWriter.flush();
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        // 当count过大时,分批下载
        public void makePartialCsv(File file, EmpService empService,int count) {
            try {
                int PartialSize=10000;
                int times=count/PartialSize;
                
                for(int i=0;i<times;i++){
                    log.info("第"+i+"批次处理");
                    
                    FileWriter fileWriter = new FileWriter(file, true);
                    
                    List<Emp> emps = empService.selectPartial(i*PartialSize, (i+1)*PartialSize);
                    
                    int index = i*PartialSize;
                    for (Emp emp:emps) {
                        index++;
    
                        String info =""+index+","+ emp.asCsvLine()+ System.getProperty("line.separator");
                        fileWriter.write(info);
                    }
    
                    fileWriter.flush();
                    fileWriter.close();
                }
                
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    Mapper.xml:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
                        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    <mapper namespace="com.hy.csvdld.dao.EmpMapper">
    
        <select id="selectTenEmp" resultType="com.hy.csvdld.Entity.Emp">
            select id,name,age,createdtime as ctime from tb01 where rownum&lt;11 order by id
        </select>
        
        <select id="selectManyEmp" resultType="com.hy.csvdld.Entity.Emp">
            select id,name,age,createdtime as ctime from tb01  where rownum&lt;#{count} order by id
        </select>
        
        <select id="selectPartialEmp" resultType="com.hy.csvdld.Entity.Emp">
            select * from (select rownum no,id,name,age,createdtime as ctime from tb01 where rownum&lt;=#{max} order by id) tbTmp where no&gt;#{min} 
        </select>
    </mapper>

    这个方案是MYSQL同类方案的新番,差别在于用rownum去替代MySql中的limit函数

    --END-- 2019年11月10日14:51:32

  • 相关阅读:
    对"对DllRegisterServer的调用失败,错误代码为0x8007005"的解决办法
    Struts FileUpload 异常处理之Processing of multipart/formdata request failed.
    Java设计模式之简单工厂模式(转载)
    [转]VS 2008 中文"试用版"变"正式版"方法
    XP系统中多用户,自动登陆(一)
    常见Flash无法播放现象处理
    [转]顺利迈出职业成功的第一步
    VS2005的BUG:Cannot convert type 'ASP.login_aspx' to 'System.Web.UI.WebControls.Login'
    OO设计原则
    ASPX页面生成HTML的方法
  • 原文地址:https://www.cnblogs.com/heyang78/p/11830217.html
Copyright © 2011-2022 走看看