有时我们希望程序里面的数据能够导出为excel方便查看,在java中可以使用第三方包poi来实现。
在maven中添加poi依赖包,
我采用的版本为3.15
使用到的类如下:
//工作簿
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
//表格
import org.apache.poi.hssf.usermodel.HSSFSheet;
//行
import org.apache.poi.hssf.usermodel.HSSFRow;
//单元
import org.apache.poi.hssf.usermodel.HSSFCell;
//单元内容
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
//单元格式
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
//字体
import org.apache.poi.hssf.usermodel.HSSFFont;
//颜色
import org.apache.poi.hssf.util.HSSFColor;
POI操作excel的方法使用起来其实很简单,大致流程是:创建工作簿HSSFWorkbook->创建表格HSSFSheet ->逐步插入每一行HSSFRow ->插入每个单元HSSFCell
demo的代码实现如下:
private <T> File exportExcel(String title, List<T> data) {
if (CollectionUtils.isEmpty(data)) {
return null;
}
// 创建一个工作薄
try (HSSFWorkbook workbook = new HSSFWorkbook()) {
// 生成一个表格
HSSFSheet sheet = workbook.createSheet(title);
// 设置表格默认列宽度为15个字节
sheet.setDefaultColumnWidth(15);
// 设置工作簿格式
HSSFCellStyle style = workbook.createCellStyle();
style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
// 设置工作簿字体
HSSFFont font = workbook.createFont();
font.setColor(HSSFColor.VIOLET.index);
font.setFontHeightInPoints((short) 12);
style.setFont(font);
//利用反射,读取列名并设置首行单元
Field[] fields = data.get(0).getClass().getDeclaredFields();
HSSFRow row = sheet.createRow(0);
int columnIndex = 0;
for (Field field : fields) {
HSSFCell cell = row.createCell(columnIndex++);
cell.setCellStyle(style);
MyAnnotation annotation = field.getAnnotation(MyAnnotation.class);
HSSFRichTextString text = new HSSFRichTextString(annotation.name());
cell.setCellValue(text);
//设置属性临时允许访问
field.setAccessible(true);
}
//遍历数据
int rowIndex = 1;
for (T item : data) {
row = sheet.createRow(rowIndex++);
columnIndex = 0;
for (Field field : fields) {
HSSFCell cell = row.createCell(columnIndex++);
cell.setCellStyle(style);
HSSFRichTextString text = new HSSFRichTextString(field.get(item).toString());
cell.setCellValue(text);
}
}
//关闭属性临时允许访问
for (Field field : fields) {
field.setAccessible(false);
}
//创建临时excel文件
File excelFile = File.createTempFile("tempExcel", ".xls");
//输出excel至输出流
try (OutputStream fos = new FileOutputStream(excelFile)) {
workbook.write(fos);
}
return excelFile;
}
上述程序的几点说明:
1. 方法exportExcel采用范型传入需导出的列表数据List< T >,注意在方法使用范型时,需在前面加上< T >标示。
2. 在遍历数据的时候需要通过java反射获取T的字段信息,
Field[] fields = data.get(0).getClass().getDeclaredFields();
3. 在设置表格的列名时,通过自定义注解MyAnnotation作用于T中每个字段,并通过反射读取该注解值,然后在表格首行设置列名。
MyAnnotation annotation = field.getAnnotation(MyAnnotation.class);
HSSFRichTextString text = new HSSFRichTextString(annotation.name());
4.代码中在try(…)内创建了工作簿和输出流,该风格可以保证打开的工作簿和输出流在离开该try作用域时保证将其关闭。允许这样操作的对象必须实现Closeable接口,比如OutputStream接口
public abstract class OutputStream implements Closeable, Flushable {
}