zl程序教程

您现在的位置是:首页 >  其他

当前栏目

项目A使用httpclient调用项目B中的POI导出excel

2023-04-18 12:32:32 时间

最近在做这样的一个需求: 我们有几套相似的后台,其中的表结构还不是完全一致,但是后台的菜单功能基本相同,我们想把这几个后台合并到一个后台中,通过下拉菜单进行后台的切换。以下简称总后台和子后台。

缕清楚需求后,我首先想到的是使用多数据源的切换,但是表结构和一些其他业务上的原因并不能完全行的通。由于项目中都是使用前后端分离做的开发,所以我想到的是直接使用拦截器,首先所有的请求都是发送到总后台,总后台根据带过来的参数判断是发往那个子后台的请求,然后去子后台发起请求。

所以这里在总后台上加上了一个拦截器,用于拦截所有的请求,然后做出判断,使用httpclient工具,将请求发送到对应的子后台,得到数据后,返回到response中,实现需求。

              String businessId = request.getHeader("businessId");
                HttpResponse resp = sendRequestByBusinessId(request, businessId, re, paramMap);//封装好的httpclient
                String result = EntityUtils.toString(resp.getEntity(), "UTF-8");
                log.debug("返回结果:"+result);
                //将调用其他平台返回的参数转成map:  直接返回可能会出错。
                Map<String, Object> resMap = JSON.parseObject(result);
                log.debug("请求参数Map===== {}",resMap);
                //将返回结果封装到response
                response.addHeader(CONTENT_TYPE, JS_TYPE);
                response.setContentType("application/json");
                response.setCharacterEncoding(CODE_UTF8);
                OutputStreamWriter out = null;
                try {
                    out = new OutputStreamWriter(response.getOutputStream(), "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    log.error(e.getMessage(), e);
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
                JsonUtil.write(out,resMap);

但是有一类需求发现使用这种方式做处理无法得到预期结果。那就是系统中还存在部分excel导出功能,都是使用poi做实现的。由于poi中自动实现了对于response和输出流的处理,使用上面的方式是没有办法实现的。那么我使用httpclient如何调用另一个系统写好的poi导出功能呢。

我们先看一下子系统中poi的实现方式。

@RequestMapping(value = "/test/export.htm")
	public void urgeLogExport(@RequestParam(value = "searchParams", required = false) String searchParams)
			throws Exception {
		Map<String, Object> params = JsonUtil.parse(searchParams, Map.class);
		List list = urgeRepayOrderService.listUrgeLog(params);
		SysUser user = (SysUser) request.getSession().getAttribute("SysUser");
		response.setContentType("application/msexcel;charset=UTF-8");
		// 记录取得
		String title = "导出Excel表";
		String[] hearders = ExportConstant.EXPORT_URGELOG_LIST_HEARDERS;
		String[] fields = ExportConstant.EXPORT_URGELOG_LIST_FIELDS;
		JsGridReportBase report = new JsGridReportBase(request, response);
		report.exportExcel(list, title, hearders, fields, user.getName());
	}
    //report.exportExcel方法如下:
/**
	 * hj
	 * Excel报表导出通用方法(含多个sheet导出)
	 * @throws Exception 
	 */
	public void exportExcel(List<Object> list,String title,String[] hearders,String[] fields,String operatorName) throws Exception{
		List<List<Object>> listResult = new ArrayList<List<Object>>();	//保存每页List的二维数组
		String excelTitle = title+"_"+DateUtil.dateStr3(DateUtil.getNow());
		if (list.size()>5000) {
			int excelSize = 5000;	//每个Excel文件条数
			int totalCount = list.size();	//查询结果总条数
			int pageCount = 0;
			int numPage = totalCount%excelSize;	//是否整页数
			if (numPage > 0) {
				pageCount = totalCount/excelSize + 1;
			}else{
				pageCount = totalCount/excelSize;
			}
			for (int i = 1; i <= pageCount; i++) {
				if (numPage == 0) {
					listResult.add(list.subList((i-1)*excelSize,excelSize*i));
				}
				else{
					if (i == pageCount) {
						listResult.add(list.subList((i-1)*excelSize,totalCount)); 
					}
					else{
						listResult.add(list.subList((i-1)*excelSize,excelSize*(i)));
					}
				}
			}
		}
		TableData td = null;
		if (listResult.size()>0) {
			List<TableData> tableDataLst = new ArrayList<TableData>();
			for (int i = 0; i < listResult.size(); i++) {
				td = ExcelUtil.createTableData(listResult.get(i), ExcelUtil.createTableHeader(hearders), fields);
				td.setSheetTitle(title + "_("+(i+1)+")");
				tableDataLst.add(td);
			}
			exportToExcel(excelTitle, operatorName, tableDataLst);
		}else{
			td = ExcelUtil.createTableData(list, ExcelUtil.createTableHeader(hearders), fields);
			exportToExcel(excelTitle, operatorName, td);
		}
	}

exportToExcel方法如下:

HSSFWorkbook wb = new HSSFWorkbook();// 创建新的Excel 工作簿

		HashMap<String, HSSFCellStyle> styles = initStyles(wb);// 根据模板文件,初始化表头样式

		wb = writeSheet(wb, title, styles, creator, tableData);// 写入工作表

		String sFileName = title + ".xls";
		/*response.setHeader("Content-Disposition",
				"attachment;filename=".concat(String.valueOf(URLEncoder.encode(sFileName, "UTF-8"))));*/
		// 火狐浏览器导出excel乱码
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		String agent = request.getHeader("User-Agent");
		// 判断是否火狐浏览器
		boolean isFirefox = (agent != null && agent.contains("Firefox"));
		if (isFirefox) {
			sFileName = new String(sFileName.getBytes("UTF-8"), "ISO-8859-1");
		} else {
			sFileName = URLEncoder.encode(sFileName, "UTF8");
		}
		response.setHeader("Content-Disposition", "attachment; filename=".concat(sFileName));
		response.setHeader("Connection", "close");
		response.setHeader("Content-Type", "application/vnd.ms-excel");
		wb.write(response.getOutputStream());

发现最终是使用wb.write写出数据,那么我们使用httpclient还怎么调用呢,这里我们先通过httpclient调用返回HttpResponse,在把他转换成InputStream ,然后穿件一个HSSFWorkbook 对象,按照上面的方式写出去即可:

              HttpResponse resp = sendRequestByBusinessId(request, businessId, re, paramMap);//封装的httpclient

                String fileName = "导出文件_"+System.nanoTime();//默认名字
                InputStream input = resp.getEntity().getContent();//转成InputStream
                HSSFWorkbook wb = new HSSFWorkbook(input);// 创建新的Excel 工作簿
                response.setHeader("Content-Disposition", "attachment; filename=".concat(fileName));
                response.setHeader("Connection", "close");
                response.setHeader("Content-Type", "application/vnd.ms-excel");
                wb.write(response.getOutputStream());

完成