Java通过Apache POI 读写Excel

170 阅读3分钟

需求场景

两千行数据,分别有英文名,中文名,和简称,现需要通过这三列的拼接得到别名用于检索。

Apache POI

Apache POI是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的首字母缩写,意为“简洁版的模糊实现”。

官方文档:Apache POI - Javadocs

导入依赖

据说poi-ooxmlpoi的升级版,不碍事,两个都导进去

        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.2.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.2</version>
        </dependency>

使用前了解

一般也就用用前两个

  • HSSF - 提供读写Microsoft Excel XLS格式档案的功能。

  • XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能。

  • HWPF - 提供读写Microsoft Word DOC97格式档案的功能。

  • XWPF - 提供读写Microsoft Word DOC2003格式档案的功能。

  • HSLF - 提供读写Microsoft PowerPoint格式档案的功能。

  • HDGF - 提供读Microsoft Visio格式档案的功能。

  • HPBF - 提供读Microsoft Publisher格式档案的功能。

  • HSMF - 提供读Microsoft Outlook格式档案的功能。

完成需求

涉及到读和写,读没什么好说的,无非是层层列表的遍历,表列表(sheet),行列表(row),到单元格列表(cell)

public class Excel {
    public static void main(String[] args) throws IOException {
        // 获取文件信息
        String path = "D:\\errors.xls";
        File file = new File(path);
        try(FileInputStream inputStream = new FileInputStream(file)){
            // 表格列表
            HSSFWorkbook sheets = new HSSFWorkbook(inputStream);
            // 获取到所要的表格,也就是第一个
            HSSFSheet sheet = sheets.getSheetAt(0);
            for (int i = 1; i < sheet.getLastRowNum(); i++) {
                // 获取当前行对象
                // 遍历每一行进行处理,因为这里知道列数量,不知道的话也可以获取
                HSSFRow row = sheet.getRow(i);
                // 因为有些字段会为空,没找到优雅一些的办法(getCell(index)会直接报空指针异常)
                String enName = null;
                try {
                    enName = row.getCell(1).getStringCellValue();
                } catch (Exception e) {
                    enName = "";
                }
                String zhName = null;
                try {
                    zhName = row.getCell(2).getStringCellValue();
                } catch (Exception e) {
                    zhName = "";
                }
                String spName = null;
                try {
                    spName = row.getCell(3).getStringCellValue();
                } catch (Exception e) {
                    spName = "";
                }
                String alias = "";

                if(enName.equals(zhName) && zhName.equals(spName)){
                    // A-A-A
                    alias = enName;
                } else if(!enName.equals(zhName) && enName.equals(spName)){
                    // A-B-A
                    alias = enName + "," + zhName;
                } else if(!enName.equals(zhName) && zhName.equals(spName)){
                    // A-B-B
                    alias = enName + "," + zhName;
                } else{
                    // A-B-C
                    alias = enName + "," + zhName + "," + spName;
                }
                // 写入操作,会覆盖
                row.createCell(4).setCellValue(alias);
            }

            // 创建输出流写数据
            try(FileOutputStream outputStream = new FileOutputStream(file)){
                sheets.write(outputStream);
            }
        }
    }
}

Excel写练习

public class Excel {
    public static void main(String[] args) throws IOException {
        String path = "D:\\students.xlsx";
        // 此处提示,XSSFWorkbook未使用try-with-resource方式,因此得知其本质也是流,需要关闭
        try(FileOutputStream outputStream = new FileOutputStream(path);
            XSSFWorkbook sheets = new XSSFWorkbook()){
            // 创建表
            XSSFSheet student = sheets.createSheet("学生信息");
            // 创建表头
            XSSFRow row = student.createRow(0);
            // 创建单元格,先创建再赋值
            row.createCell(0).setCellValue("id");
            row.createCell(1).setCellValue("name");
            row.createCell(2).setCellValue("age");

            for (int i = 1; i <= 10; i++) {
                XSSFRow curRow = student.createRow(i);
                curRow.createCell(0).setCellValue(i);
                curRow.createCell(1).setCellValue("张" + i);
                curRow.createCell(2).setCellValue(i + 18);
            }

            // 处理数据外,还可以控制格式,好像不管用,用到了再查吧
            // 设置第一列为8个字符宽
            student.setColumnWidth(0, 8 * 256);

            // 数据填充后写入
            sheets.write(outputStream);
        }
    }
}

这种练习方式太笨重,一般需求是将集合内的对象转换为表格,本来以为是有表格的构造方法的,结果没有,网上搜了个自己封装的工具类Java 实现动态将对象信息写入Excel中_To Do.的博客-CSDN博客_java将对象写入excel