在工作中经常会遇到操作excel的需求,对于格式简单、统一的excel可以选择EasyExcel来实现功能,很简单方便;而对于复杂的excel文件,如有各式各样的合并单元格、表头不固定、行列跟随业务数据动态变化……格式变幻多端的文件,easyExcel就显得无能为力了,选择poi就可以解决此问题了。
这里贴上在工作中解决问题时,自己封装的工具类,方便大家查阅:
目录
一、读取Excel、写入Excel文件工具类
二、导出Excel文件的样式设置工具类
三、写入Excel简单示例
注:poi版本为org.apache.poi:4.1.0
/**
* 工具类-使用poi读取Excel
*/
@Slf4j
public class ExcelUtilByPOI {
private static final String EXCEL_XLS = "xls";
private static final String EXCEL_XLSX = "xlsx";
/**
* 读取excel文件中的全部表格
* 描述:适用于没有单元格合并的excel,并且 (titleOfRow,titleOfColumn)位置为读取内容的起始位置的情况
* 每一行构成一个map,key值是列标题,value是列值。没有值的单元格其value值为null
* 返回结果最外层list对应excel文件,第二层Iterable对应sheet页,第三层map对应sheet页中一行
*
* @param filePath 文件路径
* @param sheetCnt 读取的文件中前sheetCnt个sheet数据。如果值为-1,则读取所有的sheet,否则,读取前sheetCnt个sheet的数据。
* @return
* @throws Exception
*/
public static List>> readExcelWithFiexPos(String filePath, int titleInRow, int titleInColumn, int sheetCnt) throws IOException {
Workbook wb = null;
try {
List>> excelData = new ArrayList<>();
if (filePath.endsWith(EXCEL_XLS) || filePath.endsWith(EXCEL_XLSX)) {
File file = new File(filePath);
wb = getWorkbook(file);
int sheetSize = sheetCnt == -1 ? wb.getNumberOfSheets() : sheetCnt;
//遍历sheet
for (int i = 0; i < sheetSize; i++) {
Sheet sheet = wb.getSheetAt(i);
List
/**
* 导出的Excel单元格样式设置
*/
public class ExcelStyleUtil {
/**
* 表头字体
*
* @return
*/
public static Font headerFoot(Workbook wb) {
Font headerFont = wb.createFont();
headerFont.setFontName("微软雅黑");
headerFont.setFontHeightInPoints((short) 13);
headerFont.setBold(true);
// headerFont.setColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
headerFont.setColor(IndexedColors.BLACK.getIndex());
return headerFont;
}
/**
* 正文字体
*
* @param wb
* @return
*/
public static Font contextFont(Workbook wb) {
Font contextFont = wb.createFont();
contextFont.setFontName("微软雅黑");
contextFont.setFontHeightInPoints((short) 13);
contextFont.setBold(false);
contextFont.setColor(IndexedColors.BLACK.getIndex());
// contextFont.setColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
return contextFont;
}
/**
* 表头样式-左右上下居中
*
* @param wb
* @return
*/
public static CellStyle headerStyle(Workbook wb) {
CellStyle headerStyle = wb.createCellStyle();
Font font = headerFoot(wb);
headerStyle.setFont(font);
headerStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中
headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
headerStyle.setLocked(true);//锁定
headerStyle.setWrapText(false);// 自动换行
headerStyle.setBorderBottom(BorderStyle.THIN);//下边框
headerStyle.setBorderTop(BorderStyle.THIN);//上边框
headerStyle.setBorderLeft(BorderStyle.THIN);//左
headerStyle.setBorderRight(BorderStyle.THIN);//右
return headerStyle;
}
/**
* 单元格样式 - 水平、垂直居中
*
* @param wb
* @return
*/
public static CellStyle contextAlignCenterStyle(Workbook wb) {
CellStyle style = wb.createCellStyle();
Font font = contextFont(wb);
style.setFont(font);
style.setAlignment(HorizontalAlignment.CENTER);//水平居中
style.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
style.setLocked(true);
style.setWrapText(true);// 自动换行
style.setBorderBottom(BorderStyle.THIN);//下边框
style.setBorderTop(BorderStyle.THIN);//上边框
style.setBorderLeft(BorderStyle.THIN);//左
style.setBorderRight(BorderStyle.THIN);//右
return style;
}
/**
* 单元格样式-无左边框
* @param wb
* @return
*/
public static CellStyle contextNoLeftBorder(Workbook wb){
CellStyle style = wb.createCellStyle();
Font font = contextFont(wb);
style.setFont(font);
style.setAlignment(HorizontalAlignment.CENTER);//水平居中
style.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
style.setLocked(true);
style.setWrapText(true);// 自动换行
style.setBorderBottom(BorderStyle.THIN);//下边框
style.setBorderTop(BorderStyle.THIN);//上边框
style.setBorderRight(BorderStyle.THIN);//右
return style;
}
/**
* 单元格样式-无左右边框
* @param wb
* @return
*/
public static CellStyle contextNoLeftRightBorder(Workbook wb){
CellStyle style = wb.createCellStyle();
Font font = contextFont(wb);
style.setFont(font);
style.setAlignment(HorizontalAlignment.CENTER);//水平居中
style.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
style.setLocked(true);
style.setWrapText(true);// 自动换行
style.setBorderBottom(BorderStyle.THIN);//下边框
style.setBorderTop(BorderStyle.THIN);//上边框
return style;
}
}
public void testWriteExcel(HttpServletRequest request, HttpServletResponse response){
//1.创建book
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet("sheet名称,可为空");
//2.创建sheet
sheet.createFreezePane(1, 2, 0, 0);//冻结首列和前两行
CellStyle headerStyle = ExcelStyleUtil.headerStyle(wb);
//3.创建行
Row row0 = sheet.createRow(0);
//4.创建单元格
Cell cell00 = row0.createCell(0);
cell00.setCellStyle(headerStyle);//设置单元格样式
cell00.setCellValue("单元格值");
CellRangeAddress mergeReion = new CellRangeAddress(0, 0, 0, 2);
sheet.addMergedRegion(mergeReion);//合并首行的前两个单元格
//(1)第二行设置表头
Row row1 = sheet.createRow(1);
for (int i = 0; i < titles.size(); i++) {
Object title = titles.get(i);
Cell cell1i = row1.createCell(i);
cell1i.setCellValue(String.valueOf(title));
cell1i.setCellStyle(headerStyle);
}
//(2)下面设置表体数据:创建10行3列的表体
CellStyle contextStyle = ExcelStyleUtil.contextAlignCenterStyle(wb);//内容样式
for (int i = 0; i < 10; i++) {
Row rowi = sheet.createRow(i + 2);
for(int j=0;j<3;j++){
Cell cellij = rowi.createCell(j);
cellij.setCellValue("单元格值");
sheet.setColumnWidth(j,5000);//设置列宽
cellij.setCellStyle(contextStyle);
}
}
//(3)导出到浏览器
try{
ExcelUtilByPOI.exportFile(request,response,wb,"文件名");//调用工具方法
}catch (Exception e){
throw new BaseException(EPowerResultCode.DOWNLOAD_FILE_FAIL);
}
}