首页 > 其他分享 >[POI]主管:你尽快封装一套读、写excel的方法,尽量简单

[POI]主管:你尽快封装一套读、写excel的方法,尽量简单

时间:2024-07-24 22:17:33浏览次数:5  
标签:return String excel new cell param POI 封装 excelPath

【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)
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);
}

最后

推荐阅读:(转发)

  1. 使用POI和EasyExcel实现Excel导入和导出功能
  2. SXSSFWorkbook:生成大Excel的低内存实现

还有一篇实用博文:《公司大佬对excel导入、导出的封装,那叫一个秒啊》(转发)。

本文完结。

标签:return,String,excel,new,cell,param,POI,封装,excelPath
From: https://www.cnblogs.com/cnb-yuchen/p/18321864

相关文章

  • easyexcel的读写操作
    easyexcel是基于java的读写excel的开源项目--读写也可理解为上传和下载写操作一、引入依赖<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.5</version></dependency>二、封装相应对象@Data@AllArgsConst......
  • 从excel列表读取图片,上传并匹配--基于03版
    主要思路:1.读取所有图片,先传到服务器本地,用row行编号命名图片名称.2.传到图片服务器,获取图片url3.与excel其它数据行匹配---------------不知为啥首尾两行不进去的分割线------------------------------publicvoidimportExcel(MultipartFilefiles)throwsException......
  • [POI2012] PRE-Prefixuffix 题解
    前言题目链接:洛谷。题意简述给出长为\(n\)的串\(\texttt{S}\)。求最大的\(l\)满足:\[2l\leqn\land\texttt{S}[1\ldotsl]\doteq\texttt{S}[n-l+1\ldotsn]\]其中\(\doteq\)表示循环相同。题目分析看到循环相同,套路化想到,两个字符串一定可以表示成\(\tex......
  • Python实现excel数据的读取和写入
    1.安装说到前面的话,实现excel文件数据的读取和写入,在python中还有其它方法,比如说pandas。鉴于最近粉丝朋友问到上面的“xlrd”和“xlwt”,那么笔者下面将通过这两个方法,来实现excel文件数据的读取和写入。首先,我们先需要提前安装好对应的库。需要注意的是,xlrd从2.0版本开始,只......
  • .NET 中高效 Excel 解决方案 MiniExcel
    前言MiniExcel是一个用于.NET平台的轻量级、高性能的库,专注于提供简单易用的API来处理Excel文件。以下是MiniExcel的特点总结:轻量级与高效:MiniExcel设计为占用较少的系统资源,尤其在内存使用上表现优秀,适合处理大数据集而不会导致内存溢出。简单易用:API设计直观,......
  • JAVA导出Excel文档水印包含中文变成乱码了(变成口了)
     在服务器执行下 fc-list:lang=zh如果为空说明没有中文字体,所以中文没法渲染,这样的话只能在项目里面自己引入字体 伪代码如下//加载外部字体文件Fontfont=null;try{InputStreamawardFontFile=Thread.currentThread().getCo......
  • 090、Python 写Excel文件及一些操作(使用xlwt库)
    要写Excel文件,我们需要使用第三方库。xlwt库是一个常用的写Excel的第三方库,它同时支持.xls和.xlsx。要使用第三方库,首选需安装:pipinstallxlwtxlutils安装完成后,我们就可以引入库来进行相关操作了。使用xrwt库写Excel文本,可以按以下步骤操作:1、第一步:创建工作簿(Wor......
  • 用Python玩转Excel的五大功能!
    在数据分析和处理的过程中,Excel一直是备受欢迎的工具。然而,手动操作Excel既费时又容易出错。幸运的是,Python可以让你高效且智能地操作Excel文件,极大提升工作效率。那么,如何用Python玩转Excel呢?  Python可以为我们提供哪些强大的功能来处理Excel文件,使得我们的数据处理工作更......
  • 【Vue】基于vue3封装批量下载功能
    一、安装依赖npminstalljszipnpminstallfile-saver 二、代码实现importaxiosfrom'axios'importJSZipfrom'jszip'importFileSaverfrom'file-saver';/***批量下载*@param{Object}fileList*/exportfunctiondownloadFileLis......
  • 从零开始学Java(超详细韩顺平老师笔记梳理)08——面向对象编程中级(上)IDEA常用快捷键、包
    文章目录前言一、IDEA使用常用快捷键模板/自定义模板二、包package1.基本介绍2.包的命名规范3.常用的包和如何引入4.注意事项和细节三、访问修饰符(四类)四、封装Encapsulation(重点)1.封装介绍2.封装步骤3.快速入门4.封装与构造器五、继承(重点)1.为什么需要继承2......