您的位置:首页 > 其它

导出List列表中的数据到Excel文件,并提供下载

2013-12-23 16:08 260 查看

整体思路

客户在页面点击“导出Excel”链接-->>进入Java逻辑处理代码-->>复制Excel模版文件-->>向这个复制过的模版文件中写入List数据-->>把数据写入完成的Excel文件下载到客户端

适用场景

数据格式固定、需要把List数据导出到Excel文件的情况下

具体代码

1.页面链接

// 添加“导出Excel”链接
		$("div#paddingDiv").append(
				"   <a href='exportStatisticsData.sp?dateStart="
						+ $("#dateStartId").val() + "&dateEnd="
						+ $("#dateEndId").val() + "&selectOrgan="
						+ $("#selectOrgan").val() + "''>导出查询结果到Excel</a>");


2.SpringMVC的ModelAndView

<!-- 工作量报表,导出Excel的Action跳转 -->
	<bean name="/exportStatisticsData.sp" class="com.peak.acc.action.ExportStatisticsAction">
		<property name="commonDao">
			<ref bean="commonDao" />
		</property>
	</bean>
try {
			// 接下来,取出数据,进行页面显示
			list = commonDao.getObjectListByArguments("queryStatisticsT", null);

			// 将数据库查询出来的列表集,转成页面展示需要的格式,单独放在一个方法里
			listShowInPage = exchangeToShowList(list, organString);

			/**
			 * 最后展示到页面上的列表元素数量
			 */
			int rows = listShowInPage.size();

			// 模版文件对象(模版在项目中有)
			File templateFirst = null;
			if (rows <= 2) {// 如果只有少于等于两行数据,就使用模版2
				templateFirst = new File(request.getRealPath("/")
						+ "upload/acc/template/Acc任务数量统计模版2.xls");
			} else {// 否则,使用模版1
				templateFirst = new File(request.getRealPath("/")
						+ "upload/acc/template/Acc任务数量统计模版1.xls");
			}
			// 使用模版,生成Excel文件的目标路径
			targetPath = "D:/acc_rm/Excel/createWhatYouWant/";

			// 拷贝模版,生成一个新的文件,用于写入统计数据,使用UUID生成唯一文件名
			String newFileName = targetPath + UUID.randomUUID().toString()
					+ ".xls";

			File newTargetFile = new File(targetPath);
			// 若目录不存在,就创建一个
			if (!newTargetFile.exists()) {
				newTargetFile.mkdirs();
			}
			// 创建目标Excel文件,.xls格式的
			newTargetFile = new File(newFileName);

			// 调用静态方法copyFile()复制模版文件 到目标文件
			AccFileUtil.copyFile(templateFirst, newTargetFile);
			log.info("任务统计的写入文件准备就绪");

			// 把数据,写入到目标文件
			createTheTargetExcel(rows, newTargetFile);

			// 附件名称
			String filename = "会计标准化任务统计报表 " + startDate + " -- " + endDate
					+ " " + organString + ".xls";
			// 设置response的编码方式
			response.setContentType("application/x-msdownload");
			// 写明要下载的文件的大小
			response.setContentLength((int) newTargetFile.length());
			// 设置下载附件的文件名
			response.setHeader("Content-Disposition", "attachment;filename="
					+ new String(filename.getBytes("GBK"), "iso-8859-1"));

			// 读出文件到i/o流
			FileInputStream fis = new FileInputStream(newTargetFile);

			byte[] b = new byte[1024];// 相当于我们的缓存
			int k = 0;// 该值用于计算当前实际下载了多少字节

			// 从response对象中得到输出流,准备下载
			OutputStream myout = response.getOutputStream();

			// 开始循环下载
			while (-1 != (k = fis.read(b, 0, b.length))) {
				// 将b中的数据写到客户端的内存
				myout.write(b, 0, k);
			}

			// 将写入到客户端的内存的数据,刷新到磁盘
			myout.flush();
			myout.close();
		} catch (Exception e) {
			log
					.info("ExportExcel  ------------------任务数量统计查询转换出现错误--------------------------:"
							+ e.getMessage());
			e.printStackTrace();
		} finally {

			// 清空列表所占有的内存
			clearAllList();

			// 最后,检查一下目录下的文件个数,大于100的话,就进行清空
			deleteDirFiles(targetPath, 100);
		}
		// 展示,这里无需返回视图
		return null;
public static void copyFile(File sourceFile, File targetFile)
			throws IOException {
		BufferedInputStream bufIS = null;
		BufferedOutputStream bufOS = null;

		try {
			// 带缓冲的输入流
			bufIS = new BufferedInputStream(new FileInputStream(sourceFile));
			// 带缓冲的输出流
			bufOS = new BufferedOutputStream(new FileOutputStream(targetFile));

			// 缓冲数组
			byte[] bytes = new byte[1024 * 5];
			// 位置记录
			int len = 0;

			while ((len = bufIS.read(bytes)) != -1) {
				// 把读入的数据流写入到输出流冲
				bufOS.write(bytes, 0, len);
			}

			// 强制写入到输出流
			bufOS.flush();

		} catch (FileNotFoundException e) {
			log.info("复制文件时找不到文件:" + e.getMessage());
			e.printStackTrace();
		} catch (IOException e) {
			log.info("复制文件时出现IO错误:" + e.getMessage());
			e.printStackTrace();
		} finally {
			// 重要:记得关闭流
			if (bufIS != null) {
				bufIS.close();
			}
			if (bufOS != null) {
				bufOS.close();
			}
		}
	}
/**
	 * 向目标Excel文件写入数据
	 * 
	 * @param rows
	 *            需要写多少行Excel
	 * @param newTargetFile
	 *            目标文件
	 * @throws IOException
	 */
	private void createTheTargetExcel(int rows, File newTargetFile)
			throws IOException {
		FileOutputStream localFile = null;
		try {
			// 获取到拷贝过后的Excel模版文件
			POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(
					newTargetFile));
			// 根据Excel文件,获取到 工作簿
			HSSFWorkbook workbook = new HSSFWorkbook(fs);

			// 获取到第一页工作表
			HSSFSheet sheet = workbook.getSheetAt(0);
			// 定义行
			HSSFRow row;

			// 列表中的把数据写入到Excel里面,从第四行开始(前三行是标题)
			for (int i = 0; i < rows; i++) {
				StatisticsShowE aline = (StatisticsShowE) listShowInPage.get(i);
				row = sheet.getRow(i + 3); // 获取第(i+3)行,前三行是标题
				// 单元格的位置,从0开始
				short tempCellCounter = 0;
				// 解决中文乱码问题(Excel文件内容里面的乱码)
				row.getCell(tempCellCounter).setEncoding(
						HSSFWorkbook.ENCODING_UTF_16);
				row.getCell(tempCellCounter).setCellValue(aline.getJgm());
				tempCellCounter++;

				// 每日
				row.getCell(tempCellCounter).setCellValue(
						aline.getMrrw().getWcCount());
				tempCellCounter++;
				row.getCell(tempCellCounter).setCellValue(
						aline.getMrrw().getWwcCount());
				tempCellCounter++;

				// 日终
				row.getCell(tempCellCounter).setCellValue(
						aline.getRzrw().getWcCount());
				tempCellCounter++;
				row.getCell(tempCellCounter).setCellValue(
						aline.getRzrw().getWwcCount());
				tempCellCounter++;
				row.getCell(tempCellCounter).setCellValue(
						aline.getRzrw().getCbCount());
				tempCellCounter++;

				// 每周
				row.getCell(tempCellCounter).setCellValue(
						aline.getMzrw().getWcCount());
				tempCellCounter++;
				row.getCell(tempCellCounter).setCellValue(
						aline.getMzrw().getWwcCount());
				tempCellCounter++;

				// 每旬
				row.getCell(tempCellCounter).setCellValue(
						aline.getMxrw().getWcCount());
				tempCellCounter++;
				row.getCell(tempCellCounter).setCellValue(
						aline.getMxrw().getWwcCount());
				tempCellCounter++;

				// 每月
				row.getCell(tempCellCounter).setCellValue(
						aline.getMyrw().getWcCount());
				tempCellCounter++;
				row.getCell(tempCellCounter).setCellValue(
						aline.getMyrw().getWwcCount());
				tempCellCounter++;
				row.getCell(tempCellCounter).setCellValue(
						aline.getMyrw().getCbCount());
				tempCellCounter++;

				// 每季
				row.getCell(tempCellCounter).setCellValue(
						aline.getMjrw().getWcCount());
				tempCellCounter++;
				row.getCell(tempCellCounter).setCellValue(
						aline.getMjrw().getWwcCount());
				tempCellCounter++;
				row.getCell(tempCellCounter).setCellValue(
						aline.getMjrw().getCbCount());
				tempCellCounter++;

				// 半年
				row.getCell(tempCellCounter).setCellValue(
						aline.getBnrw().getWcCount());
				tempCellCounter++;
				row.getCell(tempCellCounter).setCellValue(
						aline.getBnrw().getWwcCount());
				tempCellCounter++;
				row.getCell(tempCellCounter).setCellValue(
						aline.getBnrw().getCbCount());
				tempCellCounter++;

				// 每年
				row.getCell(tempCellCounter).setCellValue(
						aline.getMnrw().getWcCount());
				tempCellCounter++;
				row.getCell(tempCellCounter).setCellValue(
						aline.getMnrw().getWwcCount());
				tempCellCounter++;
				row.getCell(tempCellCounter).setCellValue(
						aline.getMnrw().getCbCount());
				tempCellCounter++;
			}

			// 新建一输出文件流
			localFile = new FileOutputStream(newTargetFile);
			// 把数据写入到相应的Excel 工作簿
			workbook.write(localFile);
			localFile.flush();
			localFile.close();
		} catch (FileNotFoundException e) {
			log.info("向Excel文件写入数据时出现异常:" + e.getMessage());
			e.printStackTrace();
		} catch (IOException e) {
			log.info("向Excel文件写入数据时出现异常:" + e.getMessage());
			e.printStackTrace();
		} finally {
			if (localFile == null) {
				// 操作结束,关闭文件
				localFile.close();
			}
		}

	}
/**
	 * 当指定的目录下,文件个数超过一定数量时,进行清空
	 * 
	 * @param path
	 * @param targetNum
	 */
	private void deleteDirFiles(String path, int targetNum) {
		File dirPath = new File(path);

		if (dirPath.exists()) {// 如果找到了这个目录
			File[] excelFiles = dirPath.listFiles();
			// 当该目录下的文件个数大于指定参数时
			if (excelFiles.length > targetNum) {
				for (int i = 0; i < excelFiles.length; i++) {
					File tempFile = excelFiles[i];
					// 日志记录删除的文件的名称
					log.info(tempFile.getName() + " 已经删除");
					if (tempFile.isFile()) {// 如果是文件,就进行删除
						tempFile.delete();
					}
				}
			}
		}
	}


注:使用的Excel解析框架是POI,此处仅提供实现思路和部分实现代码

导出效果:





最后导出的Excel文件:





模版文件:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: