本文最后更新于 2024-04-02,欢迎来到我的Blog! https://www.zpeng.site/

EXCEL导入导出poi-ooxml

1.简介

https://poi.apache.org/

Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能。是目前较流行的导入导出excel框架。

2.行数限制

        HSSFWorkbook

                缺点:最多只能处理65536行,否则会抛异常

                优点:过程中写入缓存,不操作磁盘,最后一次性吸入磁盘,速度快

        XSSFWorkbook:最大数据:1048576行,16384列,

                缺点:写数据时速度非常慢,非常耗内存,也会发生内存溢出,如100万条。

                优点:可以写较大数据量,如20万条。

        SXSSFWorkbook

                优点:可以写非常大的数据量,如100万条甚至更多条写数据速度快,占用更少的内存

        注意:

  1. 过程中会产生临时文件,需要清理临时文件

  2. 默认由100条记录被保存在内存中,如果超过这数量,则最前面的数据被写入临时文件

  3. 如果想自定义内存中数据的数量,可以使用new SXSSFWorkbook(数量)

3.依赖

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.3</version>
</dependency>

4.导入导出

4.1公用

BasicController.java

    @RequestMapping({"/", "/index"})
    public String index() {
        return "index";
    }

index.html

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form method="post" enctype="multipart/form-data" id="form">
    <div>
        <input type="file" name="uploadfile" id="wj">
    </div>

    <div class="sc">
        <input id="sc-btn" type="button" value="上传" class="btn_sc">
    </div>
</form>

<div>
    <p>批量导出:</p>
    <button id="ge" onclick="location.href='/getExcel'">获取</button>
</div>


</body>
<script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
    $("#sc-btn").click(function () {
        $.ajax({
            url: "/import",
            type: "POST",
            data: new FormData($("form")[0]),
            processData: false,
            contentType: false,
            dataType: "JSON",
            success: function () {
                alert("成功");
            }
        })
    })
</script>

</html>

User.java

package com.example.poi.demos.web;

import lombok.Data;


@Data
public class User {

    private String name;

    private Integer age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

}

4.2导入

http://127.0.0.1:8080/

    @RequestMapping("/import")
    @ResponseBody
    public void demo(MultipartFile uploadfile) throws IOException {
        List<User> datas = new ArrayList<>();//存放表格中导出的数据的实体

        InputStream is;
        try {
            is = uploadfile.getInputStream();//获取文件的流
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        //XSSFWorkbook的一个实例化对象相当于一个excel文件
        XSSFWorkbook sheets = new XSSFWorkbook(is);
        is.close();//在这里关闭流,如果放在后面关闭或者不关闭会报错:java.io.UncheckedIOException: Cannot delete XXX(一个缓存文件的路径)

        //XSSFSheet的一个实例化对象相当于excel中的一张表
        XSSFSheet sheet = sheets.getSheet("Sheet1");//或者sheets.getSheet(0),参数传入0默认是第一张表

        //sheet.getLastRowNum();获取到最后一行的索引,第一行为0.从0开始,表中有三行数据时返回2
        for (int i = 0;i <= sheet.getLastRowNum();++i){//遍历表中的每一行
            //XSSFRow的一个实例化对象相当于一张表中的一行
            XSSFRow row = sheet.getRow(i);//这里是获取表中的第i行

            //XSSFCell 的一个实例化相当于一行数据中的某一列,也就是一个表格。
            XSSFCell cell1 = row.getCell(0);//这里获取的就是第i行第0列数据
            XSSFCell cell2 = row.getCell(1);//这里获取的就是第i行第1列数据
            //从表格对象中获取到表格中的数据内容
            //不同的数据类型有不同的方法来获取
            String name = cell1.getStringCellValue();
            double age = cell2.getNumericCellValue();

            User user = new User(name, (int) age);
            datas.add(user);
        }
        System.out.println(datas);
        datas.forEach(System.out::println);
    }

4.3导出

http://127.0.0.1:8080/

    @RequestMapping("/getExcel")
    @ResponseBody
    public void demo_2(HttpServletResponse response) throws Exception {
        List<User> userlist = Arrays.asList(
                new User("张三", 18),
                new User("李四", 18),
                new User("王五", 45),
                new User("赵六", 42),
                new User("陈七", 56)
        );
        //创建一个表格文件对象
        XSSFWorkbook sheets = new XSSFWorkbook();
        //创建一个表页对象
        XSSFSheet sheet = sheets.createSheet("Sheet1");//没有形参创建的表名为Sheet0,所以推荐还是加上参数"Sheet1"
        //通过遍历将数据取出来并存放到表中
        for (int i = 0; i < userlist.size(); ++i) {
            XSSFRow row = sheet.createRow(i);
            row.createCell(0).setCellValue(userlist.get(i).getName());
            row.createCell(1).setCellValue(userlist.get(i).getAge());
        }
        //设置响应信息
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("表格1111.xlsx","UTF-8"));
        ServletOutputStream ots = response.getOutputStream();//获取到响应文件流
        sheets.write(ots);//将表格写入流中
        ots.flush();//刷新流
        ots.close();//记得关闭!
    }

5.ruoyi

        <!-- excel工具 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
        </dependency>

主要工具类

src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java

controller

    @Log(title = "角色管理", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:role:export')")
    @PostMapping("/export")
    public void export(HttpServletResponse response, SysRole role)
    {
        List<SysRole> list = roleService.selectRoleList(role);
        ExcelUtil<SysRole> util = new ExcelUtil<SysRole>(SysRole.class);
        util.exportExcel(response, list, "角色数据");
    }