导出属性对象的定义:属性对应实体类的属性名,属性名称是在excel表头显示的列名,导出列宽就是列的宽度
@ApiModel
@Data
public class ExportItem implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(notes = "属性")
private String property;
@ApiModelProperty(notes = "属性名称")
private String propertyName;
@ApiModelProperty(notes = "是否选中")
private boolean select;
@ApiModelProperty(notes = "导出列宽")
private Integer columnWide;
public ExportItem(String property, String propertyName, Integer columnWide) {
this.property = property;
this.propertyName = propertyName;
this.columnWide = columnWide;
}
}
创建excel文件对象:此方法是个泛型方法,接收属性对象的集合(template)以及要写入excel文件中的数据集合(dataList),template主要确定excel列名称以及列的宽度;
public static <T> XSSFWorkbook buildExcelXlsx(List<ExportItem> template , List<T> dataList){
if (dataList.isEmpty()){
throw new PmsException("未找到导出的数据");
}
XSSFWorkbook xssfWorkbook = null;
try {
// 创建excel文件对象
xssfWorkbook = new XSSFWorkbook();
// 获取标题样式(表头、第一行)
CellStyle titleCellStyle = createTitleCellStyle(xssfWorkbook);
// 获取内容样式
CellStyle contentCellStyle = createContentCellStyle(xssfWorkbook);
// 获取模板长度:模板是选中的导出的属性长度
int templateSize = template.size();
// 获取数据的数量
int dataSize = dataList.size();
// 定义标题行高
short titleLineHigh = 20;
// 定义内容行高
short contentLineHigh = 20;
T t = dataList.get(0);
// 获取泛型 T 的类型
Class<?> aClass = t.getClass();
// 创建sheet表
XSSFSheet sheet = xssfWorkbook.createSheet();
// 创建标题行
XSSFRow row1 = sheet.createRow(0);
// 设置标题行高
row1.setHeightInPoints(titleLineHigh);
// 设置标题
for (int i = 0 ; i < templateSize ; i++){
// 设置列宽度
sheet.setColumnWidth(i, template.get(i).getColumnWide());
// 创建标题列
XSSFCell cell = row1.createCell(i);
// 设置标题列样式
cell.setCellStyle(titleCellStyle);
// 标题列赋值
cell.setCellValue(template.get(i).getPropertyName());
}
// 设置内容
for (int i = 0 ; i < dataSize ; i++){
// 创建行
XSSFRow row = sheet.createRow(i+1);
// 设置行高
row.setHeightInPoints(contentLineHigh);
for (int j = 0 ; j < templateSize ; j++){
// 创建列
XSSFCell cell =row.createCell(j);
// 设置列样式
cell.setCellStyle(contentCellStyle);
// 获取属性名
String property = template.get(j).getProperty();
// 通过属性名获取目标属性
Field targetField = aClass.getDeclaredField(property);
// 获取目标对象(目标属性是目标对象中的一个属性)
T targetObject = dataList.get(i);
// 给列赋值
setExcelValue(cell , targetField, targetObject);
}
}
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
return xssfWorkbook;
}
创建excel标题样式与内容样式的方法;
// 创建标题样式
private static CellStyle createTitleCellStyle(XSSFWorkbook xssfWorkbook){
// 获取标题字体对象
XSSFFont titleFont = xssfWorkbook.createFont();
titleFont.setFontName("黑体");
// 设置标题字体加粗
titleFont.setBold(true);
// 设置标题字体颜色 (黑色)
titleFont.setColor((short) 0);
// 设置标题字体大小
titleFont.setFontHeightInPoints((short) 12);
// 创建标题样式
CellStyle titleCellStyle = xssfWorkbook.createCellStyle();
// 单元格样式水平居中
titleCellStyle.setAlignment(HorizontalAlignment.CENTER);
// 单元格样式垂直居中
titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 设置上右左下边框(厚边框)
titleCellStyle.setBorderTop(BorderStyle.THIN);
titleCellStyle.setBorderRight(BorderStyle.THIN);
titleCellStyle.setBorderBottom(BorderStyle.THIN);
titleCellStyle.setBorderLeft(BorderStyle.THIN);
// 将字体赋值给样式
titleCellStyle.setFont(titleFont);
return titleCellStyle;
}
// 创建内容样式
private static CellStyle createContentCellStyle(XSSFWorkbook xssfWorkbook){
// 获取标题字体对象
XSSFFont contentFont = xssfWorkbook.createFont();
contentFont.setFontName("宋体");
// 设置标题字体加粗
contentFont.setBold(false);
// 设置标题字体颜色 (黑色)
contentFont.setColor((short) 0);
// 设置标题字体大小
contentFont.setFontHeightInPoints((short) 12);
// 创建标题样式
CellStyle contentCellStyle = xssfWorkbook.createCellStyle();
// 单元格样式水平居中
contentCellStyle.setAlignment(HorizontalAlignment.CENTER);
// 单元格样式垂直居中
contentCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 设置上右左下边框(厚边框)
contentCellStyle.setBorderTop(BorderStyle.THIN);
contentCellStyle.setBorderRight(BorderStyle.THIN);
contentCellStyle.setBorderBottom(BorderStyle.THIN);
contentCellStyle.setBorderLeft(BorderStyle.THIN);
// 将字体赋值给样式
contentCellStyle.setFont(contentFont);
return contentCellStyle;
}
给cell单元格赋值的方法
// 单元格赋值
private static <T> void setExcelValue(XSSFCell cell, Field targetField, T targetObject) throws IllegalAccessException {
// 获取属性的类型
Class<?> declaringClass = targetField.getType();
// 跳过私有属性访问检查
targetField.setAccessible(true);
// 获取属性值
Object value = targetField.get(targetObject);
// 通过属性类型给excel的单元格赋值的类型;如果value为空,赋值会报错,所以为空要设置一个默认值
if (declaringClass == Short.class){
if (value == null){
cell.setCellValue(0);
}else {
cell.setCellValue((Short) value);
}
}else if (declaringClass == Integer.class){
if (value == null){
cell.setCellValue(0);
}else {
cell.setCellValue((Integer) value);
}
}else if (declaringClass == Long.class){
if (value == null){
cell.setCellValue(0);
}else {
cell.setCellValue((Long) value);
}
} else if (declaringClass == Float.class){
if (value == null){
cell.setCellValue(0.0);
}else {
cell.setCellValue((Float) value);
}
}else if (declaringClass == Double.class){
if (value == null){
cell.setCellValue(0.0);
}else {
cell.setCellValue((Double) value);
}
}else if (declaringClass == BigDecimal.class){
if (value == null){
cell.setCellValue(0.0);
}else {
cell.setCellValue(((BigDecimal) value).doubleValue());
}
}else if (declaringClass == Date.class){
if (value == null){
cell.setCellValue("");
}else {
cell.setCellValue(dateFormat.format(((Date) value)));
}
}else if (declaringClass == String.class){
if (value == null){
cell.setCellValue("");
}else {
cell.setCellValue((String) value);
}
} else {
if (value == null){
cell.setCellValue("");
}else {
cell.setCellValue(value.toString());
}
}
}
导出:创建完excel对象之后,获取一个输出流,导出即可
// 构建excel文件对象
XSSFWorkbook excelFile = ExportUtil.buildExcelXlsx(exportTemplateList, exportList);
// 获取输出流
ServletOutputStream outputStream = PmsUtil.getWebStream(response, "xlsx");
excelFile.write(outputStream);
excelFile.close();
outputStream.close();
我对XSSFWorkbook对象设置样式的理解:样式包含边框、字体等;样式只能赋值给单元格;高度是在创建行的时候设置的;列的宽度应该在创建表头的时候确定;
这篇文章是我学习POI的一个简单例子,并没有太多深入的解释,但感觉总体逻辑还清晰,希望对学习poi的你有所帮助