`
dongmingj
  • 浏览: 10065 次
文章分类
社区版块
存档分类
最新评论

异步导出excel表格(2)excel处理线程

阅读更多

        上一篇文章分享了用户下载任务的提交与下载,以及系统中对任务的保存方式,这篇文章,主要分享excel处理部分。excel处理基本流程如下:




 

        excel处理线程首先要获得生成excel表格的基本数据(其中不包括大的查询数据),保存到新创建的beansMap中;然后对于大的数据多次查询,将多次查询结果List统一保存到一个List中,最后保存到beansMap中,通过jxls生成excel报表。
 

	public void run() {
		if(orderViewService != null && pager != null) {
			if(beansMap == null)
				beansMap = new HashMap<String, Object>();
			// save query result list.
			List<OrderView> views = new LinkedList<OrderView>();
			// temp pager
			Pager tmpPager = new Pager();
			// copy pager to tmpPager
			try {
				BeanUtils.copyProperties(tmpPager, pager);
				tmpPager.setPage(1);
			} catch(InvocationTargetException e) {
				e.printStackTrace();
			} catch(IllegalAccessException e) {
				e.printStackTrace();
			}
			// query order view.
			tmpPager.setPage(1);
			tmpPager.setPageSize(SIZE_PER_PAGE);
			List<OrderView> orderViews = null;
			do {
				orderViews = orderViewService.find(tmpPager);
				tmpPager.setPage(tmpPager.getPage() + 1);
				views.addAll(orderViews);
			} while (ObjectUtil.isNotEmpty(orderViews) && orderViews.size() == 10);
			// order type
			beansMap.put("eshop", 0);
			beansMap.put("direct", 1);
			beansMap.put("distribution", 2);
			// shop list bean
			List<Eshop> shopList = eshopService.findAll();
			Map<Integer, String> shopMap = new HashMap<Integer, String>();
			for (Eshop shop : shopList) {
				shopMap.put(shop.getId(), shop.getName());
			}
			shopMap.put(-1, "-线下-");
			shopMap.put(null, "-空-");
			// logistic name map bean
			Map<Integer, String> logisticMap = new HashMap<Integer, String>();
			List<Logistic> logisticList = logisticService.findAll();
			for (Logistic logistic : logisticList) {
				logisticMap.put(logistic.getId(), logistic.getName());
			}
			// other beans
			beansMap.put("PayMode", Erp.PAYMODEMAP);
			beansMap.put("ShippingTypes", Erp.ShippingTypes.map);
			beansMap.put("OrderPayTypes", Erp.OrderPayTypes.map);
			beansMap.put("OrderStatus", Erp.OrderStatus.statusMap);
			beansMap.put("FLAGS", OrderViewServiceImpl.SELLERFLAGS);
			// current time.
			beansMap.put("CURRENT_TIME", new Date());
			beansMap.put("data", views);
			// generate excel.
			ExportResult exportResult = exportConfigService.createExportFile(jobParams.getTemplateFileCode(), jobParams.getGenerateExcelFilePath(), beansMap);
			// update job parameter.
			generateExportFile(jobParams, exportResult.getWorkBook());
		}
	}
	
	/**
	 * write <code>Workbook</code> object to file.
	 * @param jobParams job parameters
	 * @see AsynchronyExportJobParams
	 * @param workbook excel variable
	 * @see Workbook
	 * @return if success return true else return false
	 */
	private Boolean generateExportFile(AsynchronyExportJobParams jobParams, Workbook workbook) {
		// save excel into file.
		final String generateFilePrefix = Erp.contextPath + "/export/generate/";
		Boolean res = true;
		try {
			OutputStream os = new BufferedOutputStream(new FileOutputStream(generateFilePrefix + jobParams.getGenerateExcelFilePath()));
			workbook.write(os);
			os.flush();
			os.close();
		} catch(IOException e) {
			res = false;
		}
		// update job parameters in DB.
		if(res) {
			jobParams = asynchronyExportService.load(jobParams.getId());
			jobParams.setJobCurrentStatus(JobStatus.FINISHED);
			jobParams.setJobFinishTime(new Date());
			jobParams.setIsDeleteExportedFile(false);
			if(!asynchronyExportService.saveOrUpdate(jobParams))
				res = false;
		}
		return res;
	}

         对于excel的管理,我采用newSingleThreadExecutor管理,基本Service类如下:

public class ProcessOrderExportService {
	private static ExecutorService exec = Executors.newSingleThreadExecutor();
	
	/**
	 * add a job into executor queue.
	 */
	public static void pushJob(Runnable job) {
		exec.execute(job);
	}
	
	/**
	 * shutdown service.
	 */
	public static void shutdownService() {
		// interrupted all threads.
		exec.shutdown();
		// wait for two seconds.
		try {
			TimeUnit.SECONDS.sleep(2);
		} catch(InterruptedException e) {
			e.printStackTrace();
		}
		// shutdown all threads now.
		if(!exec.isShutdown())
			exec.shutdownNow();
	}
	/**
	 * restart service.
	 */
	public static void restartService() {
		if(!exec.isTerminated())
			exec.shutdownNow();
		exec = Executors.newSingleThreadExecutor();
	}
}

 这样这完成了excel导出任务的处理。对于不同的导出方式,可以创建不同的Runnable线程。线程中常见的问题就是数据的传递方式,可以采用二种方法,第一是采用数据Map<String, Object>在线程的构造方法中传递,例如:public ProcessOrderExportJob(Map<String, Object> paramMap)。第二种,线程中数据传递spring注入的方式,基本采用ApplicationContext.getBean(SomeClass.class)方式获取各种类。当然,与可以两种方式混合使用。我做异步的系统中采用SpringMVC框架,上面的线程参数传递,我采用混合的方式,线程构造方法如下:

	/**
	 * query conditions.
	 */
	private Pager pager;
	/**
	 * beans map.
	 */
	private Map<String, Object> beansMap;
	/**
	 * order view service.
	 */
	private OrderViewService orderViewService;
	/**
	 * asynchrony export job parameters service.
	 */
	private AsynchronyExportJobParamsService asynchronyExportService;
	/**
	 * export configuration service.
	 */
	private ExportConfigService exportConfigService;
	/**
	 * eshop service.
	 */
	private EshopService eshopService;
	/**
	 * logistic service.
	 */
	private LogisticService logisticService;
	/**
	 * job parameters.
	 */
	private AsynchronyExportJobParams jobParams;
	/**
	 * the constant variable of a size per page.
	 */
	private final static int SIZE_PER_PAGE = 10;
	
	public ProcessOrderExportJob(Pager pager, Map<String, Object> beansMap, AsynchronyExportJobParams jobParams) {
		this.pager = pager;
		this.beansMap = beansMap;
		this.jobParams = jobParams;
		orderViewService = Erp.context.getBean(OrderViewService.class);
		asynchronyExportService = Erp.context.getBean(AsynchronyExportJobParamsService.class);
		exportConfigService = Erp.context.getBean(ExportConfigService.class);
		eshopService = Erp.context.getBean(EshopService.class);
		logisticService = Erp.context.getBean(LogisticService.class);
	}

 在线程的构造函数中,完成了参数的初始化。

 

  • 大小: 23.9 KB
分享到:
评论

相关推荐

    多线程导出Excel(百万级别)_Java版优化.zip

    用开源 Apache POI 技术导出Excel,解决导出大数据出现OOM、栈溢出问题,此资源可实现百万级数据多线程分批导出Excel文件,不会内存溢出,生产环境已很稳定的使用者,所以用到的技术很核心、值得参考

    gridview导出excel表格

    3. **性能考虑**:对于大数据量的导出,应考虑分页导出或者后台异步导出等方式,避免阻塞UI线程。 4. **安全性**:在导出过程中,还需要注意防止XSS攻击等问题。 #### 五、总结 通过上述分析可以看出,利用ASP.NET ...

    android 导出数据到excel表格文件 .zip

    在Android平台上,将数据导出到Excel表格是一项常见的需求,特别是在数据管理和分析的应用场景中。这个.zip文件似乎包含了实现这一功能的代码或资源,命名为"familybill",可能是一个家庭账单管理应用的示例。下面...

    qml导出到excel

    - 如果数据量很大,考虑分批处理或者异步导出,以免阻塞UI。 以上就是从QML的`TableView`导出数据到Excel的关键步骤和技术。实际应用中,你可能需要根据具体的需求和环境进行调整,例如添加进度条反馈、支持自定义...

    QT 高效 导入导出excel , tableWidget显示

    在QT编程中,高效地导入和导出Excel数据并将其显示在`tableWidget`中是一项常见的需求。这里我们将深入探讨如何实现这一功能,以及优化性能的方法。QT是一个跨平台的应用程序开发框架,提供了丰富的GUI组件,`...

    C#-WinForm(2种dataGridView导出Excel)批量导出,高效率,36列万行,15秒

    1. 并行处理:如果系统资源允许,可以考虑使用多线程或异步操作,同时处理多行数据。 2. 分批次写入:将数据分批写入Excel,而不是一次性全部写入,可以降低内存占用并提高性能。 3. 内存管理:避免不必要的内存分配...

    Android数据转化为Excel表格导入导出

    "Android数据转化为Excel表格导入导出"这个主题涉及了如何在Android环境中处理数据并将其转换成Excel格式,以及如何读取Excel文件到Android应用中。这里我们将深入探讨这个过程,主要依赖于Java的一个库——jxl.jar...

    Android将数据导出为excel文件的方法

    6. **异步处理**:由于创建Excel文件可能涉及大量计算,因此建议在后台线程(如AsyncTask)中执行此操作,以免阻塞UI。 7. **处理权限问题**:对于Android 6.0及以上版本,需要在运行时请求WRITE_EXTERNAL_STORAGE...

    Android 导出数据库到Excel表格功能

    在导出数据到Excel前,你需要创建一个CSV(逗号分隔值)文件,因为CSV文件可以被大多数电子表格软件(如Excel)识别。使用FileOutputStream和BufferedWriter来写入CSV文件,每行数据用换行符分隔,每个字段用逗号...

    MVC导入与导出excel文件

    - 使用异步处理可以提高用户体验,避免长时间阻塞UI线程。 6. **异常处理**: - 编写健壮的异常处理代码,捕获可能出现的文件读写错误、格式不匹配等异常,提供友好的错误提示。 7. **单元测试**: - 对导入...

    海量千万级Excel导出源码-自动分sheet

    2. 多线程或异步处理:对于大规模数据,多线程或多进程并行处理可以提高效率,尤其是当硬件资源充足时。 3. 分页算法:在决定何时创建新的工作表时,需要一个合理的分页策略,确保每个工作表的数据量均衡且不超过...

    所见即所得-后台取指定table内容导出excel(大神出品)

    标题中的“所见即所得-后台取指定table内容导出excel”是指在Web应用程序中,用户可以在前端看到的表格(table)内容,通过后端处理,可以被精确地导出为Excel文件,实现数据的快速整理和分享。这种功能通常用于数据...

    C# datagridview控件中的数据导出EXCEL表

    在标题中提到的“C# datagridview控件中的数据导出EXCEL表”,这是一个常见的需求,尤其是在数据分析、报告生成或数据备份等场景。导出过程涉及到两个关键组件:C#编程和Microsoft Excel的交互。 1. **C#与Excel的...

    easyExcel实现大数据导出

    1. **创建实体类**:首先,你需要创建一个或多个Java实体类,这些类的属性对应Excel表格的列。例如,如果你有一个包含姓名、年龄和性别字段的表格,你可以创建如下的实体类: ```java public class User { private...

    VC 导出excel

    在VC++编程环境中,导出数据到Excel是常见的需求,特别是在数据分析、报表生成或数据交换...同时,为了提高性能,可以考虑使用多线程或异步操作,避免阻塞主程序。在处理大量数据时,注意优化内存管理和数据读写效率。

    C#导入导出Excel相关资料(各类方法总结)

    在处理大量数据时,可以使用异步操作提高性能,避免阻塞UI线程。例如,使用Task.Run或async/await关键字进行异步读写。 六、错误处理与兼容性 在导入导出过程中,应考虑文件不存在、格式错误、权限不足等异常情况...

    C#实现Excel的导入与导出

    对于大量数据的导入导出,可以考虑使用异步操作,利用多线程或异步IO提高效率。 通过以上方法,开发者可以灵活地在C#应用中实现Excel的导入导出功能,无论是进行简单的数据交换,还是复杂的报表生成,都能满足需求...

    wpf sqlite 导入导出excel

    在实际应用中,你可能会遇到一些具体问题,比如用户界面设计、多线程处理、异步操作等。这些问题需要结合WPF的MVVM(Model-View-ViewModel)设计模式和.NET Framework的功能来解决。例如,使用`BackgroundWorker`或`...

    delphi spcomm 导出excel

    总结来说,Delphi SPComm与导出Excel的结合使用,涉及串口通信、数据处理、文件操作等多个方面,需要理解并掌握这些技术,才能有效地实现从串口设备到Excel的无缝数据迁移。在具体实现时,要注意代码的整洁性和模块...

    C++Builder 导出数据到EXCEL表格

    本主题聚焦于使用C++Builder将数据导出到Excel表格,这是一个常见的需求,特别是在数据分析、报告生成以及数据库应用中。下面将详细介绍如何在C++Builder中实现这个功能。 首先,你需要一个能够处理Excel文件的库。...

Global site tag (gtag.js) - Google Analytics