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;
}
最后是表格效果