POI封装工具easyexcel导出EXCEL表样式设置



java中对Office操作比较好的工具是POI,但POI在导出数据量较大的情况下很容易因内存占用过大,而出错,阿里巴巴推出的easyexcel号称解决这一问题,几十MB的文件内存占用仅几KB,我并没有对内存占用进行测试,easyexcel吸引我的是可以一行代码导出EXCEL,这对开发人员可以说是极大的节省了开发时间,经过测试个人很满意。但导出表的样式比较丑,在网上没有找到相关文章说明,有一篇用到了反射技术,这对我这些技术新手有点难度。实际easyexcel已经提供了回调样式修改,这些与大家一起分享一下:


我个人使用的POI是4.0.0版本,新版的easyexcel是支持的,maven如下:


<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>4.0.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>4.0.0</version>
		</dependency>
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>3.1</version>
		</dependency>

easyexcel为最新版1.1.2-beta5,不知什么原因maven最高版本仅为1.1.1,所以我从GitHub下载的源码:https://github.com/alibaba/easyexcel 《一行代码完成 JAVA 的 EXCEL 读写——EasyExcel 的方法封装》参见https://yq.aliyun.com/articles/641564
下面是重点,如果想设置单元格样式,在生成ExcelWriter时使用EasyExcelFactory.getWriterWithTempAndHandler方法,单元格样式则在AfterWriteHandlerImpl()中设置

String fileName = "一个 Excel 文件";
		 String sheetName = "第一个 sheet";
		 ExcelWriter writer = EasyExcelFactory.getWriterWithTempAndHandler(null,getOutputStream(fileName, response), ExcelTypeEnum.XLSX,true,new AfterWriteHandlerImpl());
			 Sheet sheet = new Sheet(1, 3,Duty.class);
			 sheet.setSheetName(sheetName);
			 //设置列宽 设置每列的宽度
			 Map<Integer,Integer> columnWidth = new HashMap<Integer,Integer>();
			 columnWidth.put(0,11*256);columnWidth.put(1,6*256);columnWidth.put(2,7*256);columnWidth.put(3,27*256);
			 columnWidth.put(11,11*256);columnWidth.put(11,6*256);columnWidth.put(6,11*256);columnWidth.put(7,20*256);
			 sheet.setColumnWidthMap(columnWidth);
			// sheet.setTableStyle(createTableStyle(sheet));
			 writer.write(list, sheet);

AfterWriteHandlerImpl() 代码如下(个人使用)

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import com.alibaba.excel.event.WriteHandler;
import im.zhaojun.excel.PoiUtils;

public class AfterWriteHandlerImpl implements WriteHandler {
	CellStyle columnStyle;
	CellStyle columnTopStyle;
	CellStyle style;
    @Override
    public void sheet(int sheetNo, Sheet sheet) {
        Workbook workbook = sheet.getWorkbook();
        //要锁定单元格需先为此表单设置保护密码,设置之后此表单默认为所有单元格锁定,可使用		  setLocked(false)为指定单元格设置不锁定。
        //设置表单保护密码
        /eet.protectSheet("your password");
        //创建样式
		columnTopStyle = PoiUtils.getColumnTopStyle(workbook);//获取列头样式对象
		columnStyle = PoiUtils.getColumnStyle(workbook);//获取列头样式对象
		style = PoiUtils.getStyle(workbook);//单元格样式对象
        //设置是否锁
        //cellStyle.setLocked(false);
    }
    @Override
    public void row(int rowNum, Row row) {
        Workbook workbook = row.getSheet().getWorkbook();
        //设置行高
        row.setHeight((short)(1.7*256));
    }
    @Override
    public void cell(int cellNum, Cell cell) {
    	System.out.println(cellNum+"::::"+cell.getRowIndex());
        Workbook workbook = cell.getSheet().getWorkbook();
        Sheet currentSheet = cell.getSheet();
        if (cell.getRowIndex() == 0) {
        	cell.setCellStyle(columnTopStyle);
        }else if(cell.getRowIndex() == 1) {
        	cell.setCellStyle(columnStyle);
        }else{
            //设置样式
            //注意:样式最好采用公用样式,样式在创建sheet后创建,如果有多个样式也需要在创建sheet时候创建后面直接使用,不要每个Cell Create 一个样式,不然会导致报错 The maximum number
            cell.setCellStyle(style);
/*            //设置备注
            Drawing draw = currentSheet.createDrawingPatriarch();
            Comment comment = draw.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, 4, 25, 9, 30));
            XSSFRichTextString rtf = new XSSFRichTextString("添加批注内容收到货死的死哦多胡搜idsad是否会杜甫的范德萨发!1111");
            Font commentFormatter = workbook.createFont();
            commentFormatter.setFontName("宋体");
            //设置字体大小
            commentFormatter.setFontHeightInPoints((short)9);
            rtf.applyFont(commentFormatter);
            comment.setString(rtf);
            comment.setAuthor("ceshi");
            cell.setCellComment(comment);*/
        }
    }
}

附一个我单元格样式代码:

public class PoiUtils {
    /* 
     * 列头单元格样式
     */    
    public static CellStyle getColumnTopStyle(Workbook workbook) {

	// 设置字体
	Font font = workbook.createFont();
	//设置字体大小
	font.setFontHeightInPoints((short)12);
	//字体加粗
	font.setBold(true);
	//设置字体名字 
	font.setFontName("宋体");
	//设置样式; 
	CellStyle style = workbook.createCellStyle();
	//设置底边框; 
	style.setBorderBottom(BorderStyle.THIN);
	//设置底边框颜色;  
	style.setBottomBorderColor((short) 0);
	//设置左边框;   
	style.setBorderLeft(BorderStyle.THIN);
	//设置左边框颜色; 
	style.setLeftBorderColor((short) 0);
	//设置右边框; 
	style.setBorderRight(BorderStyle.THIN);
	//设置右边框颜色; 
	style.setRightBorderColor((short) 0);
	//设置顶边框; 
	style.setBorderTop(BorderStyle.THIN);
	//设置顶边框颜色;  
	style.setTopBorderColor((short) 0);
	//在样式用应用设置的字体;  
	style.setFont(font);
	//设置自动换行; 
	style.setWrapText(false);
	//设置水平对齐的样式为居中对齐;  
	style.setAlignment(HorizontalAlignment.CENTER);
	//设置垂直对齐的样式为居中对齐; 
	style.setVerticalAlignment(VerticalAlignment.CENTER);

	return style;

    }
    /* 
     * 字段样式
     */    
    public static CellStyle getColumnStyle(Workbook workbook) {

	// 设置字体
	Font font = workbook.createFont();
	//设置字体大小
	font.setFontHeightInPoints((short)10);
	//字体加粗
	font.setBold(true);
	//设置字体名字 
	font.setFontName("宋体");
	//设置样式; 
	CellStyle style = workbook.createCellStyle();
	//设置底边框; 
	style.setBorderBottom(BorderStyle.THIN);
	//设置底边框颜色;  
	style.setBottomBorderColor((short) 0);
	//设置左边框;   
	style.setBorderLeft(BorderStyle.THIN);
	//设置左边框颜色; 
	style.setLeftBorderColor((short) 0);
	//设置右边框; 
	style.setBorderRight(BorderStyle.THIN);
	//设置右边框颜色; 
	style.setRightBorderColor((short) 0);
	//设置顶边框; 
	style.setBorderTop(BorderStyle.THIN);
	//设置顶边框颜色;  
	style.setTopBorderColor((short) 0);
	//在样式用应用设置的字体;  
	style.setFont(font);
	//设置自动换行; 
	style.setWrapText(true);
	//设置水平对齐的样式为居中对齐;  
	style.setAlignment(HorizontalAlignment.CENTER);
	//设置垂直对齐的样式为居中对齐; 
	style.setVerticalAlignment(VerticalAlignment.CENTER);
	//背景色
	style.setFillForegroundColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.getIndex());// 设置背景色  
	style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
	return style;

    }

    /*  
     * 列数据信息单元格样式
     */  
    public static CellStyle getStyle(Workbook workbook) {
	// 设置字体
	Font font = workbook.createFont();
	//设置字体大小
	font.setFontHeightInPoints((short)9);
	//字体加粗
	//font.setBold(true);
	//设置字体名字 
	font.setFontName("宋体");
	//设置样式; 
	CellStyle style = workbook.createCellStyle();
	//设置底边框; 
	style.setBorderBottom(BorderStyle.THIN);
	//设置底边框颜色;  
	style.setBottomBorderColor((short) 0);
	//设置左边框;   
	style.setBorderLeft(BorderStyle.THIN);
	//设置左边框颜色; 
	style.setLeftBorderColor((short) 0);
	//设置右边框; 
	style.setBorderRight(BorderStyle.THIN);
	//设置右边框颜色; 
	style.setRightBorderColor((short) 0);
	//设置顶边框; 
	style.setBorderTop(BorderStyle.THIN);
	//设置顶边框颜色;  
	style.setTopBorderColor((short) 0);
	//在样式用应用设置的字体;  
	style.setFont(font);
	//设置自动换行; 
	style.setWrapText(false);
	//设置水平对齐的样式为居中对齐;  
	style.setAlignment(HorizontalAlignment.LEFT);
	//设置垂直对齐的样式为居中对齐; 
	style.setVerticalAlignment(VerticalAlignment.CENTER);


	return style;

    }

最后是表格效果

java个性化导出excel java导出excel样式设置_apache