工程下载地址: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

【SpringBoot/MVC】从Oracle下载百万条记录的CSV的更多相关文章

  1. 使用PL/SQL删除百万条记录的大表

    使用PL/SQL删除百万条记录的大表: 最近开发人员对测试环境数据库进行了压力测试,数据库中产生了大量的脏数据.有几张大表里数据量均在百万甚至千万条的记录数.开发人员现提出需求如下: 只清理其中的部分 ...

  2. 【原创】如何找到Oracle中哪条记录被锁

    通常有这种情况,某个表或者准确的说是表的某条记录被锁(TX锁),在业务层面排查之余,一般都会想知道是哪条记录被锁,每次被锁的是否是同一条记录?还是每次都不同?通过记录可以找到这条记录可以在哪个模块.哪 ...

  3. Oracle前10条记录

    在Oracle怎样查询表中的top10条记录呢? select * from test where rownum <=10 下面是关于rownum的介绍 ==================== ...

  4. MVC批量添加,增加一条记录的同时添加N条集合属性所对应的个体

    类别中包含一个产品的集合属性,如何向数据库添加一条类别记录的同时,添加任意多个产品. public class Product { [DisplayName("产品名称")] pu ...

  5. 【Oracle/Java】以Insert ALL方式向表中插入百万条记录,耗时9分17秒

    由于按一千条一插程序长期无反应,之后改为百条一插方式,运行完发现插入百万记录需要9m17s,虽然比MySQL效率差,但比单条插入已经好不少了. 对Oracle的批量插入语法不明的请参考:https:/ ...

  6. oracle 复制一条记录只改变主键不写全部列名

    场景:表TEST中有C1,C2,C3...字段,其中C1为主键,先需要复制表TEST中一条(C1='1'的)记录,修改主键列C1和需要变更的列后,再插入到表TEST中. procedure P_TES ...

  7. oracle count 百万级 分页查询记要总数、总条数优化

    oracle count 百万级 分页查询记录总数.总条数优化 oracle count 百万级 查询记录总数.总条数优化 最近做一个项目时,做分页时,发现分页查询速度很慢,分页我做的是两次查询,一次 ...

  8. oracle中根据当前记录查询前一条和后一条记录

    select * from aa01_2014 where aaa001=(select c.p from (select aaa001,lag(aaa001,1,0)  over (order by ...

  9. 【转】oracle 中随机取一条记录的两种方法

    oracle 中随机取一条记录的两种方法 V_COUNT INT:=0; V_NUM INT :=0; 1:TBL_MYTABLE 表中要有一个值连续且唯一的列FID BEGIN SELECT COU ...

随机推荐

  1. Vue指令之`v-text`和`v-html`

    v-text: 没有加载闪烁问题,它会覆盖元素中原本的内容,但是插值表达式,只会替换自己的这个占位符,不会把 整个元素的内容清空. v-html: 使用v-html可以把标签元素也能显示在元素上 &l ...

  2. c# 输出参数-out

  3. CIP 协议安全扫盲

  4. Luogu P5020 货币系统

    Luogu P5020 货币系统 先把$a$数组排一下序. 从最小的数开始选,显然最小这个数必须选,然后利用完全背包的思想,从$a_i$到最大值筛选一遍,将可以组成的打上标记. 在判断后面的数字时,如 ...

  5. 搭建jenkins+python+selenium+robot framework环境

    1.安装jenkins 具体参考:https://www.cnblogs.com/dydxw/p/10538103.html 2.下载插件 我是为了方便,把有关python.selenium.robo ...

  6. java中创建对象的方式

    Java中有5种创建对象的方式,下面给出它们的例子还有它们的字节码 使用new关键字 } → 调用了构造函数 使用Class类的newInstance方法 } → 调用了构造函数 使用Construc ...

  7. 修改git提交的用户名和密码

    目的:每个项目自定义Git提交的用户名和邮箱 1.在本地找到某个项目所在的地址 2.找到config文件 3.增加如下配置 4. ok,这样每个项目都可以定义提交者姓名和邮箱了

  8. Mybatis获取自增主键值

    1.配置文件变化 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLI ...

  9. CSS3限,2行3行等文字在块元素显示的文字内容超出显示省略号

    大家都知道文字超出一行显示省略号用css就可以搞定,但2行.3行等多行超出显示省略号有的人就不知怎么搞了,我用js做过一个文字判断有兴趣的可以看一下传送门,今天就来试验一下多行超出省略号 使用时注意浏 ...

  10. Laravel $request 常用方法

    request的方法 描述 input('key','default-value') 此方法可以获取get请求所带来的特定参数的值,如果没有该参数可以提供默认值 all() 此方法获取get请求的所有 ...