java导出1000个07版本的excel,时间过长该如何优化?

1.目前使用poi导出excel表格,之前用03版本可以导出2000条左右,现在换成07版本,只能导出900条左右。测试后发现导出07版本的excel花费的时间大概是03版本的3倍左右。

2.项目设置30s超时,从数据库查出来的1条数据对应一张excel,不用考虑多的sheet页,业务不允许。

3.目前是导出excel到临时文件夹,然后从临时文件夹中打包成zip包。

4.目前想法是从数据库中读取的数据转换成输出流然后存在缓存管理类中。但是输出流还要写到excel中。就是无论怎样都会进行磁盘交互。最后是要打成zip包的。这个过程如何实现呢?

2个回答

楼上说的多线程的方法你试过了吗?你确定你的程序已经出现了I/O瓶颈,你写出的单个excel数据都不小吗?如果多线程写出1000个不大的txt文件,应该是不会花多少时间的,raid5的磁盘写出速度好几百M/s还是有的吧,所以感觉是生成excel文件花了比较多的计算时间。当然我也不确定,只是感觉可以试一下多线程。
如果你想使用不写出到磁盘,直接在内存中生成最后的.zip文件的话,你也可以试一试。据我了解poi生成excel文件,最后也是写出到文件输出流;你可以在这一步改为输出到ByteArrayOutputStream,先把这个excel文件的流存在字节数组中;然后对每一个excel文件的流,新建一个zip entry,加入到你最终写出zip文件中的流去里(zip entry好像可以直接读入流创建,你可以试一下);整个过程中,不用写出中间的excel文件,而只用写出最终包含了1000个excel文件的zip文件就可以了。

qq_18727699
qq_18727699 回复WalterMills: 感谢采纳。zip entry的文件名好像可以自己定义的,不过具体还是要查查api
一年多之前 回复
WalterMills
WalterMills 多线程的方法没有试过。不过程序测试过了,确实是io的问题,之前03版本可以导出2000条,生产环境4000条,换成07版本就不行了。你的那个方法我会告诉我同事,让他试试。只不过每一个文件都有不同的名字(姓名+工号+调薪纪录值+xxxx表.xlsx),之前返回的字节数组就是还要write进去,再赋值。我还是建议使用异步来做。感谢回答。
一年多之前 回复

将1000个excel拆分为10个任务,每个任务处理100个excel,使用线程池异步操作,每个任务执行完毕后发个消息或者记录一下,等所有任务执行完毕后,打成zip包,服务器新能好的话 可以拆分成更多任务

@EnableAsync
@Configuration
class TaskPoolConfig {
//线程池
@Bean("taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(200);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("taskExecutor-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);

    return executor;
}

}

@Component
public class Task {

//线程池异步处理
@Async("taskExecutor")
public void doTask(参数。。。) throws Exception {
你的业务逻辑。。。。。
}
}

public class Tests{

@Autowired
private Task task;

@Test
public void test() throws Exception {

    task.doTask(参数。。。);

}

}

WalterMills
WalterMills 首先很感谢你的回答。但是目前的程序的瓶颈是I/O交互。我需要读取多次本地模板,然后处理,之后导出1000份excel再打包。目前的处理方法是,将模板在程序里渲染,省去了一半的时间(读取模板的时间)。而多线程处理该程序是有问题的:原因如下:程序瓶颈是i/o,采用多线程会造成多次的磁盘寻址,会极大的降低效率。cpu处理指令的速度和磁盘寻址的速度大概是百万级。另外分享下,07版本的excel导出和03版本的excel效率差了3倍。
一年多之前 回复
立即提问