JAVA-POI之Excel导出

    最近公司要求使用JAVA操作office ,研究了一天有关Excel的POI知识 ,也上网找了很多POI操作Excel的博客 ,无奈发现使用后多数代码都是过期内容,还有一部分代码使用起来操作时间过久,有的导出20000行数据慢到几乎可以睡一觉起来再看了 ,于是乎急眼自己着手搞了一个导出的Util,我是小菜鸟理解并不是太透彻,不过还是站在了巨人的肩膀上,多有借鉴各位巨人的经验,在此也多谢各位巨人们。

    那么正文开始:

    首先 导入Apache的POIjar包,没有Jar包的童鞋,可以去 ApachePOI的Jar包飞机票 下载

         

    上图为下载位置

    至于怎么导入我就不多说了(如果你不会导jar包的话,那你真该回炉了 -__-)。

    这里我只是在本地搞了一个Util类,随便弄了一个简单的bean进行测试。时间不足,仅供参考!(有了实现,不怕别的)。

    这里主要操作的是XSSFWorkBook ,03版本与07版本在代码区分改动,主要就是HSSF与XSSF的区别,命名上也就是xsl与xslx的区分,这里也就不多说了,简单研究一下,两者大同小异。

    顺便多唠叨一嘴 POI 的创建流程,方便理解。

    1、创建工作簿     (workbook)

    2、创建sheet页   (可以多个创建)

    3、创建样式        (可有可无)

    4、创建 行          

    5、创建 单元格   

    

    以下就是导出Excel的梳理代码 **

package com.excel.org;

import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.text.SimpleDateFormat;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor.HSSFColorPredefined;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExportExcelUtil {

	/**
	 * 
	 * @param sheetName		sheet页的名称
	 * @param titleName		表格标题的名称
	 * @param headers		表格列头的名称数组
	 * @param data			数据源
	 * @param resultUrl		本地的地址
	 * @param pattern		时间的格式
	 */
	private static void doExportExcel07(String sheetName,String titleName,String[] headers,Collection<?> data,String resultUrl,String pattern) {

		// 声明一个工作薄
		XSSFWorkbook workbook = new XSSFWorkbook();
		OutputStream out=null;

		// 生成一个工作表
		XSSFSheet sheet = workbook.createSheet(sheetName);
		// 设置工作表默认列宽度为20个字节
		sheet.setDefaultColumnWidth((short) 20);
		//设置工作表的默认高度为14个字节
//		sheet.setDefaultRowHeight((short) 14);
		//在工作表中合并首行并居中
		sheet.addMergedRegion(new CellRangeAddress(0,0,0,headers.length-1));

		/** start 关于标题 start **/
		
		// 创建[标题]样式
		XSSFCellStyle titleStyle = workbook.createCellStyle();
		// 设置[标题]样式
		titleStyle.setFillForegroundColor(IndexedColors.DARK_YELLOW.getIndex()); 	//屎黄色
		titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);			    //填充模式
		titleStyle.setBorderBottom(BorderStyle.THIN);					            //下边框样式
		titleStyle.setBorderLeft(BorderStyle.THIN);					                //左边框样式
		titleStyle.setBorderRight(BorderStyle.THIN);					            //右边框样式
		titleStyle.setBorderTop(BorderStyle.THIN);					                //上边框样式
		titleStyle.setAlignment(HorizontalAlignment.CENTER);				        //居中
		//创建[标题]字体
		XSSFFont titleFont = workbook.createFont();
		//设置[标题]字体
		titleFont.setColor(IndexedColors.BLUE.getIndex());				            //蓝色
		titleFont.setFontHeightInPoints((short) 24);					           //字体大小
		titleFont.setFontName("Courier New");						                //字体样式
		titleFont.setBold(true);                                                   //是否粗体
		// 应用
		titleStyle.setFont(titleFont);
		//设置标题的座标 并 赋值
		XSSFRow titleRow = sheet.createRow(0);
		XSSFCell titleCell = titleRow.createCell(0);
		titleCell.setCellStyle(titleStyle);
		titleCell.setCellValue(titleName);

		/** end 关于标题 end **/
		
		
		/** start 关于列头 start **/
		
		// 创建[列头]样式
		XSSFCellStyle headersStyle = workbook.createCellStyle();
		// 设置[列头]样式
		headersStyle.setFillForegroundColor(IndexedColors.BLUE.index);	    //颜色
		headersStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);		//填充模式
		headersStyle.setBorderBottom(BorderStyle.THIN);						//下边框样式
		headersStyle.setBorderLeft(BorderStyle.THIN);						//左边框样式
		headersStyle.setBorderRight(BorderStyle.THIN);						//右边框样式
		headersStyle.setBorderTop(BorderStyle.THIN);						//上边框样式
		headersStyle.setAlignment(HorizontalAlignment.CENTER);				//居中
		//创建[列头]字体
		XSSFFont headersFont = workbook.createFont();
		//设置[列头]字体
		headersFont.setColor(HSSFColorPredefined.VIOLET.getIndex());
		headersFont.setFontHeightInPoints((short) 12);
		// 应用
		headersStyle.setFont(headersFont);
		// 设置列头的座标 并 循环赋值
		XSSFRow row = sheet.createRow(1);
		for (short i = 0; i < headers.length; i++) {
			XSSFCell cell = row.createCell(i);
			cell.setCellStyle(headersStyle);
			XSSFRichTextString text = new XSSFRichTextString(headers[i]);
			cell.setCellValue(text);
		}

		/** end 关于列头 end **/

		
		/** start 关于表中数据 start **/
		// 创建[表中数据]样式
		XSSFCellStyle dataSetStyle = workbook.createCellStyle();
		// 设置[表中数据]样式
		dataSetStyle.setFillForegroundColor(HSSFColorPredefined.LIGHT_ORANGE.getIndex());
		dataSetStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		dataSetStyle.setBorderBottom(BorderStyle.THIN);
		dataSetStyle.setBorderLeft(BorderStyle.THIN);
		dataSetStyle.setBorderRight(BorderStyle.THIN);
		dataSetStyle.setBorderTop(BorderStyle.THIN);
		dataSetStyle.setAlignment(HorizontalAlignment.CENTER);
		dataSetStyle.setVerticalAlignment(VerticalAlignment.CENTER);
		// 创建[表中数据]字体
		XSSFFont dataSetFont = workbook.createFont();
		// 设置[表中数据]字体
		dataSetFont.setColor(IndexedColors.BLUE.getIndex());
		// 应用
		dataSetStyle.setFont(dataSetFont);
		
		
		/**此处多谢某位前辈省去了我一部分时间,我把前辈的代码稍作修改以达到更效率的方式,望见谅**/
		// 创建表中数据行-增加样式-赋值
		Iterator<?> it = data.iterator();
		int index = 1;
		while (it.hasNext()) {
			index++;
			row = sheet.createRow(index);   
			Object t = it.next();
			// 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
			Field[] fields = t.getClass().getDeclaredFields();
			for (short i = 0; i < fields.length; i++) {
				XSSFCell cell = row.createCell(i);
				cell.setCellStyle(dataSetStyle);
				Field field = fields[i];
				String fieldName = field.getName();
				String getMethodName = "get"+ fieldName.substring(0, 1).toUpperCase()+ fieldName.substring(1);
				try {
					@SuppressWarnings("rawtypes")
					Class tCls = t.getClass();
					@SuppressWarnings("unchecked")
					Method getMethod = tCls.getMethod(getMethodName,new Class[] {});
					Object value = getMethod.invoke(t, new Object[] {});

					// 如果是时间类型,按照格式转换
					String textValue = null;
					if (value instanceof Date) {
						Date date = (Date) value;
						SimpleDateFormat sdf = new SimpleDateFormat(pattern);
						textValue = sdf.format(date);
					} else {
						// 其它数据类型都当作字符串简单处理
						if (value != null) {
							textValue = value.toString();
						}else {
							textValue = "";
						}
					}
					// 利用正则表达式判断textValue是否全部由数字组成
					if (textValue != null) {
						Pattern p = Pattern.compile("^\\d+(\\.\\d+)?$");
						Matcher matcher = p.matcher(textValue);
						if (matcher.matches()) {
							// 是数字当作double处理
							cell.setCellValue(Double.parseDouble(textValue));
						} else {
							// 不是数字做普通处理
							cell.setCellValue(textValue);
						}
					}
				} catch (SecurityException e) {
					e.printStackTrace();
				} catch (NoSuchMethodException e) {
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}
		}
		try {
			out = new FileOutputStream(resultUrl);
			workbook.write(out);
			out.flush();
			out.close();
			workbook.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

        
        
	public static void main(String[] args) throws Exception{

		String sheetName="我是sheet页名字";
		String titleName="我是标题";
		String[] headers = { "我是列头1号", "我是列头2号", "我是列头3号", "我是列头4号" };
		
		List<TestBean> data = new ArrayList<>();
		for (int i = 0; i < 50000; i++) { 
			TestBean b = new TestBean();			//这里写一个javaBean  里面有几个参数 不多做介绍 循环添加了5万次
			b.setid(String.valueOf(i));
			b.setMoney("19.21");
			b.setName("新年快乐" + i);
			b.setDate(java.sql.Date.valueOf("2018-02-24"));
			data.add(b);
		}
		
		//测试一下使用时间
		long end,start;
		start = System.currentTimeMillis();
		
		String resultUrl="F:\\新建文件夹\\显灵吧!.xlsx";
		String pattern="yyyy-MM-dd";
		ExportExcelUtil.doExportExcel07(sheetName, titleName, headers, data, resultUrl, pattern);
		end = System.currentTimeMillis();
		
		System.out.println((end - start) /1000 );
	}
}


运行了一下,5万行的简单数据,我的电脑大概是 7~10秒左右。 还算中肯。 接下来还有新任务,欢迎各位大佬指点、批评!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章