这个demo的主题是 使用EasyExcel把数据库导出为excel,多少条为一个excel文件,并把这些文件打包到一个固定位置,然后下载这个包文件
目前各种参数都是写死的,使用的是 生产消费者模式 在一个队列中放数据,取数据。
放一下关键代码:
启动项目时启动一个线程:
//被spring容器管理publicclassMyApplicationRunnerimplementsApplicationRunner { publicvoidrun(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 中的导出方法,传一个表名进来,条件可选:
value= {"/export/{tableName}"}) (publicvoidexport(StringtableName ,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(); } publicvoidrun() { 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; }
先上效果图,在列表页面点击导出按钮,然后在一个文件表中添加一条数据,查看导出状态,完成后有一个下载地址