JAVA POI读写excel

   在开发管理软件时,经常需要对Excel进行读写操作,JAVA常用的操作Excel方式有jcob和POI(下载地址:http://download.csdn.net/detail/shuizhaoshui/9523962),POI纯JAVA环境,不需要安装office引用,但对office的兼容性比jcob稍次点,但对我们平时的开发已经足够,因此,我更倾向于使用POI进行excel处理,在.NET开发中添加NPOI引用,起到同样的效果。今天发表的这篇文章是对POI读写Excel的两个封装通用方法,对基础的导出Excel和读取Excel相对还是方便的,好了,直接上代码。

1、读取Excel

	@SuppressWarnings({ "static-access" })
	private static String getCellValue(HSSFCell hssfCell) {
		if (hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN) {
			return String.valueOf(hssfCell.getBooleanCellValue());
		} else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC) {
			return String.valueOf(hssfCell.getNumericCellValue());
		} else {
			return String.valueOf(hssfCell.getStringCellValue());
		}
	}
    因为cell中存在不同的数据类型,上面方法是读取每个cell中值,转为字符串类型以便通用处理(其实不用统一转为字符串类型也可以,但是那样读取操作,判断相对复杂很多,不仅要对cell类型进行判断,还要通过反射对实体类型进行判断转换, 对平常的读取感觉没必要,可以放到统一的集合中(集合所有字段全部为string类型)提取完之后再进行类型转换,将一个通用的实体结合转换为自己需要的实体对象,我感觉这样还稍微方便一点。所以会建立一个字段足够多的javabean对象,用来数据统一处理


然后就到 真正操作读取的方法了,如下所示:

/**
	 * 读取Excel
	 * @param 要读取的Excel路径信息
	 * @param c 读入的实体类型(ExportFields)
	 * @return 返回读取的list结果
	 * @throws IOException
	 * @throws Exception
	 * @throws IllegalAccessException
	 */
	public static <T> List<T> ReadExcel(String filepath, Class<T> c)
			throws IOException, Exception, IllegalAccessException {
		List<T> list = new ArrayList<T>();
		Field[] fields = c.getDeclaredFields();
		InputStream is = new FileInputStream(filepath);  //网络传输可改动 request.getInputStream()
		@SuppressWarnings("resource")
		HSSFWorkbook hbook = new HSSFWorkbook(is); //读取的内容
		HSSFSheet xssfSheet = hbook.getSheetAt(0);//要读取的sheet</span>
		if (xssfSheet == null) {
			return list;
		}
                  //逐行逐列进行读取
              for (int rowNum = 1, rowcount = xssfSheet.getLastRowNum(); rowNum <= rowcount; rowNum++) {
			HSSFRow xssfRow = xssfSheet.getRow(rowNum);
			if (xssfRow == null) {
				continue;
			}
			T obj = c.newInstance();//新建对象实例
			for (int celNum = 0, celCount = xssfRow.getLastCellNum(); celNum < celCount; celNum++) {
				HSSFCell hssCel = xssfRow.getCell(celNum);
				String result = "";
				if (hssCel != null) {
					result = getCellValue(hssCel);
				}
				fields[celNum].setAccessible(true);//反射访问私有字段必设
				fields[celNum].set(obj, result);//字段赋值
			}
			list.add(obj);
		}
		return list;
	}

在一 个项目中上面读取方法的形参class对象就可以统一用自己建立的ExportFields 对象来处理,提取结束后,你可以把转换为自己需要的对象,不管是Person对象还是Students对象,如果你自己对象所有字段都为string类型,那么可以直接传入自己建立的对象, 因此,上面的调用方法可以统一为:

List<ExportFields> list=ReadExcel("文件路径名",ExportFields.class);
对取完之后就可以对list集合进行自己需要的处理。

如果是网络传输读取可以对方法稍加改动,不用存储到本地,直接进行网络读取操作,读取代码可以这样来写。

	public static <T> List<T> ReadExcel(HttpServletRequest request,String filepath, Class<T> c)
			throws IOException, Exception, IllegalAccessException {
		List<T> list = new ArrayList<T>();
		InputStream is = request.getInputStream();
2、导出Excel

   导出Excel相对更方便一点,考虑字段类型不用那么复杂,代码如下:

	/**
	 * 导出操作布
	 * @param list 要传入的导出集合
	 * @param excelname 导出后的文件名及sheet名
	 * @param titles 导出excel的每列的名称
	 * @return 
	 */
	private static <T> HSSFWorkbook Hssbook(List<T> list, String excelname,
			String... titles) {

		HSSFWorkbook hbook = new HSSFWorkbook();
		HSSFSheet sheet = hbook.createSheet(excelname);
		HSSFRow row = sheet.createRow(0);//默认导出的sheet 0,如果想导出多个sheet可以自己加参数判断  
		HSSFCellStyle hstyle = hbook.createCellStyle();
		hstyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); //标题水平居中对齐
		int count = titles.length;  //cell标题的长度
		for (int i = 0; i < count; i++) {
			HSSFCell cell = row.createCell(i);
			cell.setCellValue(titles[i]); //设置cell值
			cell.setCellStyle(hstyle);
			sheet.autoSizeColumn(i); //默认列宽度,如果需要自己可以设置指定宽度
		}
		Field[] fields = list.get(0).getClass().getDeclaredFields();  //获取要导出的字段属性
		int fcoount = fields.length > count ? count : fields.length; //判断导出字段的长度,限定不会超过标题的长度
		for (int i = 0, countl = list.size(); i < countl; i++) {
			row = sheet.createRow(i + 1);
			for (int j = 0; j < fcoount; j++) {
				Field field = fields[j];
				field.setAccessible(true); //私有字段必设
				String fileString = "";
				try {
					Object obj = field.get(list.get(i)); //字段取值
					if (obj != null) {
						fileString = obj.toString(); //全部以字符串类型导出
					}
					row.createCell(j).setCellValue(fileString); //cell赋值
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return hbook;
	}
字段的cell取值顺序是跟自己建立的对象的位置 顺序是一致的。默认每列必须有标题,这个是防止字段过多未赋值就不用对后面未赋值的字段读取。注释够详细了,具体的我也就不解释了,读取方法在后面,如下:

	/**
	 *  Excel 导出 
	 * @param response
	 * @param list 要导出的List集合
	 * @param excelname  导出Excel的文件名和sheet名
	 * @param titles 导出excel的列标题
	 * @return 导出状态
	 */
	public static <T> String ExportExcel(HttpServletResponse response,
			List<T> list, String excelname, String... titles) {
		if (excelname == null || excelname.isEmpty()) {
			excelname = new Date().getTime() + "";//如果标题未设置或者为空,则取当前时间<span style="font-family:arial, 宋体, sans-serif, tahoma, 'Microsoft YaHei';">值</span>
		}
		HSSFWorkbook hbook = Hssbook(list, excelname, titles);
		response.setContentType("application/vnd.ms-excel");
		try {
			excelname = new String(excelname.getBytes("UTF-8"), "ISO-8859-1");//编码类型
		} catch (Exception e2) {
		}
		response.setHeader("Content-disposition", "attachment;filename="
				+ excelname + ".xls");
		OutputStream ouputStream = null;

		try {
			ouputStream = response.getOutputStream();
			hbook.write(ouputStream);
			ouputStream.flush();
			ouputStream.close();
			hbook.close();
		} catch (Exception e) {
			try {
				ouputStream.close();
				hbook.close();
			} catch (Exception e1) {
			}
			return "false";
		}
		return "ok";
	
	}
上面要注意的是这句

excelname = new String(excelname.getBytes("UTF-8"), "ISO-8859-1");
这个编码类型要注意,防止中文标题乱码,java web里面默认的为 ISO-8859-1类型,因此要进行 转码处理。

在springMVC里面调用方法可以这样:

    @RequestMapping(value = "ExportExcel")    
	    public void ExportExcel(HttpServletRequest request, HttpServletResponse response)     
	    throws Exception { 	    	
	        List<Person> listPerson = new ArrayList<Person>(); 
	         Person p1=new Person();
	         listPerson.add(p1);
	          String[] titles={ "测试","邮箱","年龄","姓名","其他"};
	          ExcelUtil.ExportExcel(response, listPerson,"测试title",titles);	 
	        //  List<ExportFields> listExportFields= new ArrayList<ExportFields>(); 
	         //ExcelUtil.ExportExcel(response, listPerson, "测试title","邮箱","年龄","姓名","其他");	         	
	    }

上面形参传入的集合对象List<T>可以是 已经定义通用统一集合对象List<ExportFields> 或者其他你想传入的对象集合List<Person>。

页面请求方式如下:

<input type="button" οnclick="ExportExcel()" value="导出EXCEL" />
<script type="text/javascript">
function ExportExcel(){    
    location.href="ExportExcel";//请求地址
} 
</script>

好了,结束 基本的读取写入Excel方法,.NET开发中处理excel方法和这个差不多,下载相关程序集 ,利用反射,操作也挺方便的。

如果啥地方不对或者需要优化的地方还请大家批评指出,我会尽快改正,谢谢!






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值