[POI]主管:你尽快封装一套读、写excel的方法,尽量简单
【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)
https://www.cnblogs.com/cnb-yuchen/p/18321864
出自【进步*于辰的博客】
方法简单,也出于个人时间考虑,就未作过多注释和说明,可谓,本文只有代码,但相信你一看便懂。
读
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 ""; } }
写
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导入、导出的封装,那叫一个秒啊》(转发)。
本文完结。
分类:
Java知识点
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Blazor Hybrid适配到HarmonyOS系统
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 解决跨域问题的这6种方案,真香!
· 分享4款.NET开源、免费、实用的商城系统
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库