通过多线程读取数据,使用EasyExcel按顺序导出数据
导出时如果要保证顺序需要使用单线程,但是查询时可以用多线程,因为多线程查询后返回数据不是按照顺序排列的,所以我的思路是再循环时给每个线程打标识,通过标识来排序多线程返回的结果
创建一个Future对象,用于排序多线程查询结果
static class Result { final Integer threadId; final List < UserInfo > data; Result ( Integer threadId, List < UserInfo > data) { this . threadId = threadId; this . data = data; } }
@PostMapping ( "export3" ) public void export3 ( HttpServletResponse response) throws IOException , InterruptedException , ExecutionException { Long dataCount = userInfoMapper. selectCount ( ) ; Long searchCount = 100000L ; int ceil = ( int ) Math . ceil ( ( double ) dataCount / searchCount) ; ExecutorService executorService = Executors . newFixedThreadPool ( Runtime . getRuntime ( ) . availableProcessors ( ) ) ; List < Future < Result > > futures = new ArrayList < > ( ) ; Map < Integer , Result > resultsMap = new ConcurrentHashMap < > ( ) ; for ( int i = 1 ; i <= ceil; i++ ) { Integer pageNum = Math . toIntExact ( ( i - 1 ) * searchCount) ; int finalI = i; futures. add ( executorService. submit ( ( ) -> new Result ( finalI, userInfoMapper. getList ( pageNum, searchCount) ) ) ) ; } for ( Future < Result > future : futures) { resultsMap. put ( future. get ( ) . threadId, future. get ( ) ) ; } List < Result > sortedResults = resultsMap. values ( ) . stream ( ) . sorted ( Comparator . comparingInt ( result -> result. threadId) ) . collect ( Collectors . toList ( ) ) ; WriteCellStyle headWriteCellStyle = new WriteCellStyle ( ) ; headWriteCellStyle. setHorizontalAlignment ( HorizontalAlignment . CENTER) ; WriteCellStyle contentWriteCellStyle = new WriteCellStyle ( ) ; contentWriteCellStyle. setHorizontalAlignment ( HorizontalAlignment . CENTER) ; HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy ( headWriteCellStyle, contentWriteCellStyle) ; response. setHeader ( "Content-Disposition" , "attachment; filename=test" + DateUtil . format ( new Date ( ) , "yyyyMMddHHmmss" ) + ".xlsx" ) ; response. setContentType ( "application/vnd.ms-excel" ) ; response. setCharacterEncoding ( "UTF-8" ) ; ExcelWriter excelWriter = EasyExcelFactory . write ( response. getOutputStream ( ) , UserInfo . class ) . registerWriteHandler ( horizontalCellStyleStrategy) . needHead ( true ) . excelType ( ExcelTypeEnum . XLSX) . build ( ) ; WriteSheet writeSheet = EasyExcelFactory . writerSheet ( "Sheet1" ) . head ( UserInfo . class ) . registerWriteHandler ( new LongestMatchColumnWidthStyleStrategy ( ) ) . registerWriteHandler ( horizontalCellStyleStrategy) . build ( ) ; try { sortedResults. forEach ( r -> excelWriter. write ( r. data, writeSheet) ) ; } finally { executorService. shutdown ( ) ; excelWriter. finish ( ) ; } }