Java 使用线程把数据库导出为excel

简介: 这是一个demo,内有不足请谅解

这个demo的主题是 使用EasyExcel把数据库导出为excel,多少条为一个excel文件,并把这些文件打包到一个固定位置,然后下载这个包文件

目前各种参数都是写死的,使用的是 生产消费者模式  在一个队列中放数据,取数据。

放一下关键代码:

启动项目时启动一个线程:

@Component//被spring容器管理publicclassMyApplicationRunnerimplementsApplicationRunner {
@Overridepublicvoidrun(ApplicationArgumentsargs) throwsException {
System.out.println("-------------->"+"项目启动,now="+newDate());
ExcelThread.startExcelThread();
    }
}

这是一个全局的阻塞队列:

publicclassQueueUtil {
publicstaticBlockingQueue<Object>queue=newLinkedBlockingQueue<>();
publicstaticObjectget() throwsException{
//        return queue.poll(2, TimeUnit.SECONDS); //不阻塞returnqueue.take(); //阻塞    }
publicstaticvoidput(Objectobj) throwsException{
queue.put(obj);
    }
}

这是Controller   中的导出方法,传一个表名进来,条件可选:

@RequestMapping(value= {"/export/{tableName}"})
publicvoidexport(@PathVariableStringtableName ,Stringname){
//        System.out.println(tableName+"---"+name.length());  user---0if (name.length()==0){
service.exportZIP(tableName);
        }else {
service.exportZIP(tableName, name);
        }
    }

这是Service  这里往队列中存入数据:

publicvoidexportZIP(StringtableName){
try {
QueueUtil.put(tableName);
    }catch (Exceptione){
e.printStackTrace();
System.out.println("存入数据失败");
    }
}
publicvoidexportZIP(StringtableName,Stringname){
try {
QueueUtil.put(tableName+":"+name);
    }catch (Exceptione){
e.printStackTrace();
System.out.println("存入数据失败");
    }
}

线程类  在这把队列中的数据取出来:

publicclassExcelThreadextendsThread{
privatestaticStringPATH="/file/";
privatestaticStringExcelName="用户信息表";
privatestaticStringTYPE=".xlsx";
//    @Value("${zip.name}")privatestaticStringZIP_NAME="用户信息";
privatestaticintSIZE=5000 ;
privateBlockingQueuequeue=QueueUtil.queue;
publicstaticExcelThreadexcelThread=null;
privateFilesServicefilesservice= (FilesService) ApplicationContextUtil.getBean("filesServiceImpl");
publicstaticvoidstartExcelThread(){
if (excelThread==null){
excelThread=newExcelThread();
        }
excelThread.start();
    }
@Overridepublicvoidrun() {
try {
while (true) {
Stringstr= (String) QueueUtil.get(); //《============String[] split=str.split(":");
zip(split);
            }
        } catch (Exceptione) {
e.printStackTrace();
        }
    }
publicvoidzip(String[] str) {
OutputStreamoutputStream;
ZipOutputStreamzipOutputStream;
Serviceservice= (Service) ApplicationContextUtil.getBean(str[0]+"ServiceImpl");
longdate=System.currentTimeMillis();
ZIP_NAME+=date;
Stringpath=System.getProperty("user.dir") +PATH+ZIP_NAME+".zip";
filesservice.alter();
intid=filesservice.save(newFiles(ZIP_NAME,newDate(date)));
try {
outputStream=newFileOutputStream(path);
zipOutputStream=newZipOutputStream(outputStream);
intcount=0;
if (str.length>1){
count=service.count(str[1]);
            }else {
count=service.count();
            }
count=count/SIZE+(count%SIZE==0?0:1);
for (Integeri=0; i<count; i++) {
byte[] buf=newbyte[1024];
List<User>userList;
if (str.length>1){
userList=service.selectPage(i+1,5000,str[1]);
                }else {
userList=service.selectPage(i+1,5000).getRecords();
                }
byte[] content=newFileUtil().excelTableStream(userList).toByteArray(); //返回一个excel文件ByteArrayInputStreamis=newByteArrayInputStream(content);
BufferedInputStreambis=newBufferedInputStream(is);
zipOutputStream.putNextEntry(newZipEntry(ExcelName+(i+1)+TYPE)); //压缩文件条目intlen;
while ((len=bis.read(buf)) >0) {
zipOutputStream.write(buf, 0, len);
                }
zipOutputStream.closeEntry();
bis.close();
is.close();
zipOutputStream.flush();
System.out.println(ExcelName+(i+1)+TYPE+"导出完成");
            }
zipOutputStream.close();
outputStream.close();
        } catch (Exceptione) {
e.printStackTrace();
        }finally {
filesservice.updateState(id,PATH+ZIP_NAME+".zip");
        }
    }
publicstaticvoidmain(String[] args) {
Datenow=newDate(); // 创建一个Date对象,获取当前时间// 指定格式化格式SimpleDateFormatf=newSimpleDateFormat("yyyy年MM月dd日 HH点mm分ss秒");
System.out.println(f.format(now)); // 将当前时间袼式化为指定的格式    }
}

把一个结果集生产一个excel:

publicByteArrayOutputStreamexcelTableStream(List<User>userList) {
try {
ByteArrayOutputStreambyteArrayOutputStream=newByteArrayOutputStream();
EasyExcel.write(byteArrayOutputStream, User.class)
//.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) 自动列宽  数字不起作用                .sheet("用户信息")
                .doWrite(() -> {
// 查询数据returnuserList;
                });
returnbyteArrayOutputStream;
    } catch (Exceptione) {
e.printStackTrace();
    }
returnnull;
}


先上效果图,在列表页面点击导出按钮,然后在一个文件表中添加一条数据,查看导出状态,完成后有一个下载地址

image.png

image.png

目录
相关文章
|
15天前
|
缓存 easyexcel Java
Java EasyExcel 导出报内存溢出如何解决
大家好,我是V哥。使用EasyExcel进行大数据量导出时容易导致内存溢出,特别是在导出百万级别的数据时。以下是V哥整理的解决该问题的一些常见方法,包括分批写入、设置合适的JVM内存、减少数据对象的复杂性、关闭自动列宽设置、使用Stream导出以及选择合适的数据导出工具。此外,还介绍了使用Apache POI的SXSSFWorkbook实现百万级别数据量的导出案例,帮助大家更好地应对大数据导出的挑战。欢迎一起讨论!
116 1
|
5天前
|
Java API Apache
|
7天前
|
SQL Java 数据库连接
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率。本文介绍了连接池的工作原理、优势及实现方法,并提供了HikariCP的示例代码。
20 3
|
8天前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
20 4
|
7天前
|
存储 Java 关系型数据库
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践,包括连接创建、分配、复用和释放等操作,并通过电商应用实例展示了如何选择合适的连接池库(如HikariCP)和配置参数,实现高效、稳定的数据库连接管理。
20 2
|
7天前
|
Java 数据库连接 数据库
如何构建高效稳定的Java数据库连接池,涵盖连接池配置、并发控制和异常处理等方面
本文介绍了如何构建高效稳定的Java数据库连接池,涵盖连接池配置、并发控制和异常处理等方面。通过合理配置初始连接数、最大连接数和空闲连接超时时间,确保系统性能和稳定性。文章还探讨了同步阻塞、异步回调和信号量等并发控制策略,并提供了异常处理的最佳实践。最后,给出了一个简单的连接池示例代码,并推荐使用成熟的连接池框架(如HikariCP、C3P0)以简化开发。
21 2
|
10天前
|
Java 数据库连接 数据库
优化之路:Java连接池技术助力数据库性能飞跃
在Java应用开发中,数据库操作常成为性能瓶颈。频繁的数据库连接建立和断开增加了系统开销,导致性能下降。本文通过问题解答形式,深入探讨Java连接池技术如何通过复用数据库连接,显著减少连接开销,提升系统性能。文章详细介绍了连接池的优势、选择标准、使用方法及优化策略,帮助开发者实现数据库性能的飞跃。
18 4
|
7天前
|
Java 数据库连接 数据库
深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能
在Java应用开发中,数据库操作常成为性能瓶颈。本文通过问题解答形式,深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能。文章介绍了连接池的优势、选择和使用方法,以及优化配置的技巧。
11 1
|
7天前
|
Java 数据库连接 数据库
Java连接池在数据库性能优化中的重要作用。连接池通过预先创建和管理数据库连接,避免了频繁创建和关闭连接的开销
本文深入探讨了Java连接池在数据库性能优化中的重要作用。连接池通过预先创建和管理数据库连接,避免了频繁创建和关闭连接的开销,显著提升了系统的响应速度和吞吐量。文章介绍了连接池的工作原理,并以HikariCP为例,展示了如何在Java应用中使用连接池。通过合理配置和优化,连接池技术能够有效提升应用性能。
22 1
|
7天前
|
监控 Java 数据库连接
在Java开发中,数据库连接管理是关键问题之一
在Java开发中,数据库连接管理是关键问题之一。本文介绍了连接池技术如何通过预创建和管理数据库连接,提高数据库操作的性能和稳定性,减少资源消耗,并简化连接管理。通过示例代码展示了HikariCP连接池的实际应用。
13 1