[POI]主管:你尽快封装一套读、写excel的方法,尽量简单
【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)
https://www.cnblogs.com/cnb-yuchen/p/18321864
出自【进步*于辰的博客】
方法简单,也出于个人时间考虑,就未作过多注释和说明,可谓,本文只有代码,但相信你一看便懂。
1、读
1、文件兼容类型。
// 兼容文件后缀列表
private static final String FILE_TYPE;
static {
// 注:XSSFWorkBook 类支持这三种后缀的文件,不过必须由xlsx文件修改后缀而来
FILE_TYPE = ".xls/.xlsx/.csv";
}
2、文件检查。
/**
* 文本薄文件有效性检查
*
* @param excelPath 文本薄文件路径
*/
public static void checkFile(String excelPath) throws Exception {
/**
* XSSFWorkBook 底层会检查:
* 1、文件是否存在;
* 2、文件类型:不能是目录,仅支持xls、xlsx、csv等类型文件。
* (不过,底层异常提示不够人性化,故自主开发)
*/
if (excelPath == null || excelPath.equals(""))
throw new Exception("文件路径不能为空");
File f = new File(excelPath);
if (f.exists()) {
if (f.isDirectory())
throw new Exception("指定文件不能是目录");
} else
throw new Exception("文件不存在");
// 注:程序能运行到此,说明文件存在且不是目录,即 excelPath 一定是一个文件的绝对路径,故无需再构造 File 对象获取绝对路径
// 检查文件后缀
String suffix = excelPath.substring(excelPath.lastIndexOf("."));
if (FILE_TYPE.indexOf(suffix) == -1) {
throw new Exception("不是文本薄文件");
}
}
3、读取文本薄。
/**
* 读取excelPath所指的文本薄文件
*
* @param excelPath 文本薄文件路径
* @param sheetIndex 文本簿索引
*/
public static List<Map<String, String>> readExcel(String excelPath, int sheetIndex) throws Exception {
List<Map<String, String>> dataList = new ArrayList<>();
// 检查文件
checkFile(excelPath);
XSSFWorkbook workbook = new XSSFWorkbook(excelPath);// 获取数据到工作簿
if (sheetIndex < 0 || sheetIndex >= workbook.getNumberOfSheets())
throw new Exception("此文本薄条目不存在");
XSSFSheet sheet = workbook.getSheetAt(sheetIndex);// 获取第n张表
XSSFRow titleRow = sheet.getRow(0);// 标题行
for (int i = 1; i < sheet.getPhysicalNumberOfRows(); i++) {// 数据从第二行开始
Map<String, String> dataMap = new HashMap<>();
XSSFRow dataRow = sheet.getRow(i);// 数据行
if (dataRow == null) // 排除空行(当当行所有列全为空时,此行不存在)
continue;
if (!isValidRow(dataRow)) // 排除无效行
continue;
for (int j = 0; j < dataRow.getPhysicalNumberOfCells(); j++) {
XSSFCell titleCell = titleRow.getCell(j);// 表头
XSSFCell dataCell = dataRow.getCell(j);// 数据
dataMap.put(titleCell.getStringCellValue(), getCellValue(dataCell));
}
dataList.add(dataMap);
}
workbook.close();
return dataList;
}
4、判断是否是无效行。
/**
* 判断数据行是否有效,
* 判断依据:第一列是否有内容
*
* @param dataRow 数据行
*/
private static boolean isValidRow(XSSFRow dataRow) {
XSSFCell cell0 = dataRow.getCell(0);
if (cell0 != null)
return true;
return false;
}
5、获取单元格数据。
/**
* 根据cell值类型获取值
* 注:无论文本列是何种类型,都转为String
*
* @param cell 文本列
*/
protected static String getCellValue(XSSFCell cell) {
CellType type = cell.getCellType();
if (type == CellType.BLANK) {
return "";
} else if (type == CellType.NUMERIC) {// 数字、时间
return cell.getNumericCellValue() + "";
} else if (type == CellType.BOOLEAN) {
return cell.getBooleanCellValue() + "";
} else if (type == CellType.STRING) {
return cell.getStringCellValue().trim();
} else if (type == CellType.ERROR) {
return cell.getErrorCellString();
} else {
return "";
}
}
2、写
1、将封装在List<Map<String, String>>
内的数据导出excel。
/**
* 导出excel
* @param dataList 数据集
* @param sheetName 文本薄名称
* @param titleArr 表头数组
* @return 导出行数
*/
public static int writeExcel0(List<Map<String, String>> dataList, String excelPath, String sheetName, String... titleArr)
throws Exception {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet0 = workbook.createSheet(sheetName);
// 设置表头
XSSFRow row0 = sheet0.createRow(0);
for (int i = 0; i < titleArr.length; i++) {
XSSFCell cell = row0.createCell(i);
cell.setCellValue(titleArr[i]);
}
int rowN = 1;
for (Map<String, String> map : dataList) {
XSSFRow row = sheet0.createRow(rowN++);
int colN = -1;
while (colN++ < titleArr.length - 1) {
XSSFCell cell = row.createCell(colN);
cell.setCellValue(map.get(getTitle(row0, colN)));// 根据列索引获取列名,再获取内容
}
}
workbook.write(new FileOutputStream(excelPath));// 覆盖
workbook.close();
return dataList.size();
}
2、返回表头名称。
/**
* 返回表头名称
*
* @param titleRow 表头行
* @param colN 列索引
* @return
*/
private static String getTitle(XSSFRow titleRow, int colN) {
return titleRow.getCell(colN).getStringCellValue();
}
3、将封装在List<String[]>
内的数据导出excel。
/**
* 导出excel
* 注:若实参类型为List<List<String>>,源码相同,未保留是因为认为实用性不大
*/
public static int writeExcel(List<String[]> dataList, String excelPath, String sheetName, String... titleArr)
throws Exception {
List<Map<String, String>> newList = new ArrayList<>();
dataList.forEach(e -> {
Map<String, String> map = new HashMap<>();
int i = 0;
for (String str: e) {
map.put(titleArr[i++], str);
}
newList.add(map);
});
return writeExcel0(newList, excelPath, sheetName, titleArr);
}
最后
推荐阅读:(转发)
还有一篇实用博文:《公司大佬对excel导入、导出的封装,那叫一个秒啊》(转发)。
本文完结。