POI导入导出Excel数据(IDEA版)简单运用

一、POI

Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能,简单来说就是能在Java程序中导入导出Word,Excel,PPT,Visio等文件内容。

二、使用POI

运行环境:
IDEA 2019.3.3 x64
JDK 1.8.0_241
Maven 3.6.3

我将以Excel表格的导入导出为例,演示如何使用POI。

1.创建Maven项目

新建Maven项目,通过模板创建可以更快捷。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

配置电脑中已安装的Maven在这里插入图片描述

2.pom.xml文件添加依赖

在下图位置添加POI依赖:
在这里插入图片描述
导入依赖如下:

<!--  POI依赖  -->
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>3.17</version>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>3.17</version>
    </dependency>

pom.xml文件完整代码如下:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>poi_demo</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>poi_demo Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <!--  POI依赖  -->
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>3.17</version>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>3.17</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>poi_demo</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

3.导出

代码如下:

import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class POIdemo {
    // Excel数据导出
    public static void main(String[] args) {
        // Excel2003版本(包含2003)以前使用HSSFWorkbook类,扩展名为.xls
        // Excel2007版本(包含2007)以后使用XSSFWorkbook类,扩展名为.xlsx

        // 创建工作簿类
        XSSFWorkbook workbook = new XSSFWorkbook();

        // 创建工作表并设置表名
        XSSFSheet sheet = workbook.createSheet("学生信息");

        // 创建行,下标从0开始
        XSSFRow row = sheet.createRow(0);

        // 在行中创建列并赋值,下标从0开始
        row.createCell(0).setCellValue("学号");
        row.createCell(1).setCellValue("姓名");
        row.createCell(2).setCellValue("专业");
        row.createCell(3).setCellValue("班级");

        row = sheet.createRow(1);

        row.createCell(0).setCellValue("2018010627");
        row.createCell(1).setCellValue("赵国庆");
        row.createCell(2).setCellValue("软件工程");
        row.createCell(3).setCellValue("软件1806");

        // 设置Excel文件路径
        File file = new File("C:\\Users\\lenovo\\Desktop\\poi_demo.xlsx");

        try {
            // 创建指向该路径的输出流
            FileOutputStream stream = new FileOutputStream(file);

            // 将数据导出到Excel表格
            workbook.write(stream);

            // 关闭输出流
            stream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行效果图:
在这里插入图片描述

4.导入

代码如下:

import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.*;

public class POIdemo {
    // Excel数据导出
    public static void main(String[] args) {
        // 创建文件并指定文件路径
        File file = new File("C:\\Users\\lenovo\\Desktop\\poi_demo.xlsx");

        try {
            // 创建改文件的输入流
            FileInputStream stream = new FileInputStream(file);

            // 创建工作簿
            XSSFWorkbook workbook = new XSSFWorkbook(stream);

            // 获取一个工作表,下标从0开始
            XSSFSheet sheet = workbook.getSheetAt(0);

            // 通过循环,逐行取出表中每行数据
            for(int i=0;i<=sheet.getLastRowNum();i++){
                // 获取行
                XSSFRow row = sheet.getRow(i);

                // 获取行中列的数据
                String[] value = new String[4];

                value[0] = row.getCell(0).getStringCellValue();
                value[1] = row.getCell(1).getStringCellValue();
                value[2] = row.getCell(2).getStringCellValue();
                value[3] = row.getCell(3).getStringCellValue();

                for (String data:value) {
                    System.out.println(data);
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行效果图:
在这里插入图片描述

三、自定义工具类

/**
 * author:赵国庆
 * date:2023/1/14
 * name:Excel导入/导出工具类
 */
public class ExcelTool {

    /**
     * message:Excel导出功能
     * @param excelName Excel文件名
     * @param excelOutPath Excel文件保存路径
     * @param rowList Excel的内容
     * @return
     */
    public String excelOut(String excelName, String excelOutPath, ArrayList<ArrayList> rowList) {

        String status = "0";    // 设置导出方法执行结果,0失败,1成功,2成功但文件名已存在
        String message = "";    // 设置提示信息
        JSONObject obj = new JSONObject();      // 存放执行信息status和message

        // 创建工作簿类
        // Excel2003版本(包含2003)以前使用HSSFWorkbook类,扩展名为.xls
        // Excel2007版本(包含2007)以后使用XSSFWorkbook类,扩展名为.xlsx
        XSSFWorkbook workbook = new XSSFWorkbook();

        // 创建工作表并设置表名,表名为 传入的表名参数,请注意工作表名不是Excel文件名
        XSSFSheet sheet = workbook.createSheet(excelName);
        // 工作表中的行
        XSSFRow row = null;

        // rowList为预导出的数据集,结构为ArrayList套ArraList,外层为行,里层为列,如下图所示
        // [                                        excel内容
        //      [第一列, 第二列, 第三列 ...],        excel第一行
        //      [第一列, 第二列, ...],            excel第二行
        //      [第一列, ...],                 excel第三行
        //      ...                         以此类推
        // ]
        int rowNum = 0;     // 行下标

        // 创建excel行
        for (ArrayList<String> colList: rowList) {
            row = sheet.createRow(rowNum);
            int colNum = 0;     // 列下标

            // 对每行逐列插入值
            for (String colValue: colList) {
                row.createCell(colNum).setCellValue(colValue);
                colNum++;
            }

            rowNum++;
        }

        // 设置Excel文件路径,例如:E:\ + 学生表 + 20230114(这是我自己写的时间获取方法,别人用不了,删了就行) + .xlsx
        String excelFileName = excelOutPath + excelName + CalendarTool.getTodayNum() + ".xlsx";
        File outExcleFile = new File(excelFileName);
        int fileVersion = 0;

        // 判断路径下是否存在同名文件,如果不进行判断,会覆盖同名文件内容,造成同名信息丢失
        // 所以,若存在同名文件,给文件名加(1)、(2)这样的标识
        while (outExcleFile.exists()) {
            fileVersion++;
            excelFileName = excelOutPath + excelName + CalendarTool.getTodayNum() + "(" + fileVersion + ").xlsx";
            outExcleFile = new File(excelFileName);
        }

        try {
            // 创建指向该路径的输出流
            FileOutputStream stream = new FileOutputStream(outExcleFile);

            // 将数据导出到Excel表格
            workbook.write(stream);

            // 关闭输出流
            stream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();

            System.out.println("excel导出失败。");
            obj.put("status", status);
            obj.put("message", "excel导出失败。");

            return obj.toJSONString();

        } catch (IOException e) {
            e.printStackTrace();
        }

        if (fileVersion == 0) {
            System.out.println("导出成功,保存路径为:" + excelFileName);
            obj.put("status", "1");
            obj.put("message", "导出成功,保存路径为:" + excelFileName);

            return obj.toJSONString();
        } else {
            System.out.println("导出成功,保存路径为:" + excelFileName);
            obj.put("status", "2");
            obj.put("message", "导出成功,保存路径为:" + excelFileName);

            return obj.toJSONString();
        }
    }

	/**
     * message:Excel导出功能,浏览器下载
     * @param excelName Excel文件名
     * @param rowList Excel的内容
     * @return
     */
    public String excelOutOnBrowser(HttpServletResponse resp, String excelName, ArrayList<ArrayList> rowList) {

        String status = "0";    // 设置导出方法执行结果,0失败,1成功,2成功但文件名已存在
        String message = "";    // 设置提示信息
        JSONObject obj = new JSONObject();      // 存放执行信息status和message

        // 创建工作簿类
        // Excel2003版本(包含2003)以前使用HSSFWorkbook类,扩展名为.xls
        // Excel2007版本(包含2007)以后使用XSSFWorkbook类,扩展名为.xlsx
        XSSFWorkbook workbook = new XSSFWorkbook();

        // 创建工作表并设置表名,表名为 传入的表名参数,请注意工作表名不是Excel文件名
        XSSFSheet sheet = workbook.createSheet(excelName);
        // 工作表中的行
        XSSFRow row = null;

        // rowList为预导出的数据集,结构为ArrayList套ArraList,外层为行,里层为列,如下图所示
        // [                                        excel内容
        //      [第一列, 第二列, 第三列 ...],        excel第一行
        //      [第一列, 第二列, ...],            excel第二行
        //      [第一列, ...],                 excel第三行
        //      ...                         以此类推
        // ]
        int rowNum = 0;     // 行下标

        // 创建excel行
        for (ArrayList<String> colList: rowList) {
            row = sheet.createRow(rowNum);
            int colNum = 0;     // 列下标

            // 对每行逐列插入值
            for (String colValue: colList) {
                row.createCell(colNum).setCellValue(colValue);
                colNum++;
            }

            rowNum++;
        }

        // 设置Excel文件名,例如:学生表 + 20230114(这是我自己写的时间获取方法,别人用不了,删了就行) + .xlsx
        String excelFileName = excelName + CalendarTool.getTodayNum() + ".xlsx";

        try {
            // 设置响应格式,让浏览器知道是下载操作
            resp.setContentType("applicaton/x-mdownload");
            // 设置下载后的文件名
            resp.setHeader("Content-Disposition", "atachment;filename=" + new String(excelFileName.getBytes("utf-8"),"ISO8859-1"));
            // 设置响应编码
            resp.setContentType("text/html;charcet=UTF-8");
            // 建立输出流的连接
            OutputStream outputStream = resp.getOutputStream();

            // 将数据导出到Excel表格
            workbook.write(outputStream);

            // 关闭输出流
            outputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();

            System.out.println("excel导出失败。");
            obj.put("status", status);
            obj.put("message", "excel导出失败。");

            return obj.toJSONString();

        } catch (IOException e) {
            e.printStackTrace();
        }

        status = "1";
        obj.put("status", status);
        obj.put("message", "excel导出成功。");

        return obj.toJSONString();
    }

    /**
     * name:Excel导入功能
     * remark:该Excel导入功能,是一张表对应一个实体类,一行对应一条实体对象信息,一列对应一项实体对象属性
     * 所以针对不同实体类,需要进行微调
     * @param excelFile 预导入的Excel文件
     * @return
     */
    public List<Student> excelInput(MultipartFile excelFile) {

        String excelFileName = excelFile.getOriginalFilename();     // 获取excel文件名
        int excelVersion = getExcelVersion(excelFileName);          // 获取excel文件的版本

        Workbook workbook = null;
        List<Student> studentList = null;

        // 2003版本xls
        if (excelVersion == 1) {
            try {
                workbook = new HSSFWorkbook(excelFile.getInputStream());
                studentList = readExcelValue(workbook);

                return studentList;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // 2007版本xlsx
        if (excelVersion == 2) {
            try {
                workbook = new XSSFWorkbook(excelFile.getInputStream());
                studentList = readExcelValue(workbook);

                return studentList;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    // 判断要导入的excel信息,0代表未接收到,1代表2003版,2代表2007版
    public int getExcelVersion(String excelFileName) {
        int flag = 0;

        if (excelFileName.matches("^.+\\.(?i)(xls)$")) {
            flag = 1;
        }

        if (excelFileName.matches("^.+\\.(?i)(xlsx)$")) {
            flag = 2;
        }

        return flag;
    }

    // 读取Excel内容,将其放入对应的实体对象中
    private List<Student> readExcelValue(Workbook workbook) {

        int totalRows = 0;
        int totalCells = 0;

        // 获取第一张表
        Sheet sheet = workbook.getSheetAt(0);

        // 得到表的总行数
        totalRows = sheet.getPhysicalNumberOfRows();

        // 根据第一行(标题行)获得总列数,获得总列数得根据某行确定
        if (totalRows >= 1 && sheet.getRow(0) != null) {
            totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
        }

        List<Student> studentList = new ArrayList<>();

        // 逐行取数据,每行对应一条实体对象信息
        for (int rowNum = 1; rowNum < totalRows; rowNum++) {
            // 跳过标题行
            Row row = sheet.getRow(rowNum);

            if (row == null){
                continue;
            }

            Student student = new Student();
            // 逐列取数据,每列对应一个实体对象属性
            for (int colNum = 0; colNum < totalCells; colNum++) {
                System.out.println("第" + (rowNum + 1) + "行,第" + (colNum + 1) + "列");

                Cell cell = row.getCell(colNum);

                if (null != cell) {
                    if (colNum == 0) {           //第一列
                        // 如果是纯数字,将单元格类型转为String
                        if(cell.getCellTypeEnum() != CellType.STRING){
                            cell.setCellType(CellType.STRING);
                        }
                        student.setId(Long.valueOf(cell.getStringCellValue()));
                    }
                    else if (colNum == 1){
                        if(cell.getCellTypeEnum() != CellType.STRING){
                            cell.setCellType(CellType.STRING);
                        }
                        student.setName(cell.getStringCellValue());
                    }
                    else if (colNum == 2){
                        if(cell.getCellTypeEnum() != CellType.STRING){
                            cell.setCellType(CellType.STRING);
                        }

                        student.setAge(Integer.valueOf(cell.getStringCellValue()));
                    }
                    else if (colNum == 3){
                        if(cell.getCellTypeEnum() != CellType.STRING){
                            cell.setCellType(CellType.STRING);
                        }
                        student.setSex(cell.getStringCellValue());
                    }
                }
            }

            // 添加到studentList
            studentList.add(student);
        }

        return studentList;
    }
}
  • 23
    点赞
  • 111
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值