文档章节

使用Apache POI生成和读取excel文件

阿信sxq
 阿信sxq
发布于 2017/06/05 15:30
字数 1681
阅读 104
收藏 2

在项目中经常出现的需求就是,需要将表格形式的数据导出或者将表格形式的数据导入,当然我们可以使用简单的文本格式,使用csv作为后缀,客户也可以使用excel打开,但是那样会出现各种奇怪的问题,比较常见的就是乱码。

在java里面其实已经有了很好的操作库,可以很容易的进行excel文件的操作,那就是Apache POI,本文将延时如何使用poi中的接口,对表格形式数据进行导出和导入。

注:poi还有操作其他文档的库,就不做讨论了。

添加依赖

我们使用maven进行项目的构建管理,在依赖中添加下面的配置即可

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

由于excel文件一般有xls后缀和xlsx后缀,这两种文件有较大差异,操作的api是单独的,上面的依赖是操作xlsx所必须的依赖,maven会自动寻找它所以来的poi的组件,如果仅仅是需要操作xls文件,那么可以直接配置

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.16</version>
</dependency>

本文的项目为了演示两种api的操作,使用的poi-ooxml的组件。

关于项目代码已经上传到了码云,https://git.oschina.net/songxinqiang/BlogExampleCode,可以自行查看

准备

为了演示的需要,我准备了一个模型类,用于表示表格的“一行”,就是一个简单的POJO

public class User implements Serializable {

    private static final long serialVersionUID = 5643553301653588278L;

    private int id;
    private String username;

    public User() {}

    public User(int id, String username) {
        this.id = id;
        this.username = username;
    }

    @Override
    public String toString() {
        return "{id:" + id + ",username:" + username + "}";
    }

    //set、get

}

为了实现导出,我们还需要准备一些数据

List<User> userList = new ArrayList<>();
userList.add(new User(1, "test1"));
userList.add(new User(2, "test2"));
userList.add(new User(3, "test3"));
userList.add(new User(4, "test4"));
userList.add(new User(5, "test5"));
userList.add(new User(6, "test6"));
userList.add(new User(7, "test7"));
userList.add(new User(8, "test8"));

导出表格到文件

将前面的list数据保存到一个文件中,我们需要建立一个excel文件的描述对象,在这个对象中添加数据即可。

如开始时所述,xls和xlsx的文件时不同的,下面分别给出两个方法,首先是操作xls文件的

    /**
     * 将用户列表转换存入xls文件
     *
     * @param userList
     *            用户信息列表
     * @return 保存的临时文件的信息对象,用于后续操作
     */
    public File userListToFile(List<User> userList) {
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet spreadsheet = workbook.createSheet("用户列表");

        // 用于第一行的样式,当做标题
        HSSFFont font = workbook.createFont();
        font.setFontHeightInPoints((short) 14);
        font.setItalic(true);
        font.setBold(true);
        HSSFCellStyle style = workbook.createCellStyle();
        style.setFont(font);

        HSSFRow row;
        Cell cell;
        int rowid = 0;
        int cellid = 0;
        row = spreadsheet.createRow(rowid++);
        row.setRowStyle(style);
        row.setHeightInPoints(27);

        cell = row.createCell(cellid);
        cell.setCellValue("编号");
        spreadsheet.setColumnWidth(cellid, 18 * 256);
        cellid++;

        cell = row.createCell(cellid);
        cell.setCellValue("用户名");
        spreadsheet.setColumnWidth(cellid, 18 * 256);
        cellid++;

        for (User user : userList) {
            try {
                cellid = 0;
                row = spreadsheet.createRow(rowid++);

                cell = row.createCell(cellid++);
                cell.setCellValue(user.getId());
                cell = row.createCell(cellid++);
                cell.setCellValue(user.getUsername());
            } catch (Exception e) {
                logger.error("parse list error," + e.getMessage());
            }
        }
        // 文件只是临时文件,在方法返回之后,对文件进行后续的移动位置等操作
        File file = new File("/tmp/userlist.xls");
        try {
            FileOutputStream fos = new FileOutputStream(file);
            workbook.write(fos);
        } catch (Exception e) {
            logger.error("write file failed," + e.getMessage());
        } finally {
            try {
                workbook.close();
            } catch (IOException e1) {
                logger.error("close workbook error," + e1.getMessage());
            }
        }
        return file;
    }

然后是xlsx文件的

    /**
     * 将用户列表转换存入xlsx文件
     *
     * @param userList
     *            用户信息列表
     * @return 保存的临时文件的信息对象,用于后续操作
     */
    public File userListToFile(List<User> userList) {
        XSSFWorkbook workbook = new XSSFWorkbook(XSSFWorkbookType.XLSX);
        XSSFSheet spreadsheet = workbook.createSheet("用户列表");

        // 用于第一行的样式,当做标题
        XSSFFont font = workbook.createFont();
        font.setFontHeightInPoints((short) 14);
        font.setItalic(true);
        font.setBold(true);
        XSSFCellStyle style = workbook.createCellStyle();
        style.setFont(font);

        XSSFRow row;
        Cell cell;
        int rowid = 0;
        int cellid = 0;
        row = spreadsheet.createRow(rowid++);
        row.setRowStyle(style);
        row.setHeightInPoints(27);

        cell = row.createCell(cellid);
        cell.setCellValue("编号");
        spreadsheet.setColumnWidth(cellid, 18 * 256);
        cellid++;

        cell = row.createCell(cellid);
        cell.setCellValue("用户名");
        spreadsheet.setColumnWidth(cellid, 18 * 256);
        cellid++;

        for (User user : userList) {
            try {
                cellid = 0;
                row = spreadsheet.createRow(rowid++);

                cell = row.createCell(cellid++);
                cell.setCellValue(user.getId());
                cell = row.createCell(cellid++);
                cell.setCellValue(user.getUsername());
            } catch (Exception e) {
                logger.error("parse list error," + e.getMessage());
            }
        }
        // 文件只是临时文件,在方法返回之后,对文件进行后续的移动位置等操作
        File file = new File("/tmp/userlist.xlsx");
        try {
            FileOutputStream fos = new FileOutputStream(file);
            workbook.write(fos);
        } catch (Exception e) {
            logger.error("write file failed," + e.getMessage());
        } finally {
            try {
                workbook.close();
            } catch (IOException e1) {
                logger.error("close workbook error," + e1.getMessage());
            }
        }
        return file;
    }

可以看到,他们在操作上大体的方法是一样的,只有少许的差异,具体的代码的意义,还是需要查询javadoc文档的,通过这个方法我们就得到了一个保存有列表中数据的File对象,可以用于后续的处理,在这里我们直接用于文件中数据导入的数据源。

导入表格数据到程序

和导出一样,导入也需要分文件类型进行操作,下面首先是导入xls文件数据的

    /**
     * 读取文件中的值得到记录列表
     *
     * @param file
     *            文件描述信息
     * @return 记录对象列表
     */
    public List<User> fileToList(File file) {
        List<User> userList = new ArrayList<>();
        HSSFWorkbook workbook = null;
        try {
            NPOIFSFileSystem poifs = new NPOIFSFileSystem(file);
            workbook = new HSSFWorkbook(poifs);
        } catch (Exception e) {
            logger.error("read file error:" + e.getMessage());
            return userList;
        }
        HSSFSheet spreadsheet = workbook.getSheetAt(0);
        int rowCount = spreadsheet.getLastRowNum();
        HSSFRow row;
        // 第一行忽略
        for (int rowId = 1; rowId <= rowCount; rowId++) {
            row = spreadsheet.getRow(rowId);

            User user = new User();

            // 这里获取“数字”类型的值得到的是double
            user.setId((int) row.getCell(0).getNumericCellValue());
            user.setUsername(row.getCell(1).getStringCellValue());

            userList.add(user);
        }
        try {
            workbook.close();
        } catch (IOException e) {}

        return userList;
    }

接下来,是xlsx文件的操作

    /**
     * 读取文件中的值得到记录列表
     *
     * @param file
     *            文件描述信息
     * @return 记录对象列表
     */
    public List<User> fileToList(File file) {
        List<User> userList = new ArrayList<>();
        XSSFWorkbook workbook = null;
        try {
            workbook = new XSSFWorkbook(file);
        } catch (Exception e) {
            logger.error("read file error:" + e.getMessage());
            return userList;
        }
        XSSFSheet spreadsheet = workbook.getSheetAt(0);
        int rowCount = spreadsheet.getLastRowNum();
        XSSFRow row;
        // 第一行忽略
        for (int rowId = 1; rowId <= rowCount; rowId++) {
            row = spreadsheet.getRow(rowId);

            User user = new User();

            // 这里获取“数字”类型的值得到的是double
            user.setId((int) row.getCell(0).getNumericCellValue());
            user.setUsername(row.getCell(1).getStringCellValue());

            userList.add(user);
        }
        try {
            workbook.close();
        } catch (IOException e) {}

        return userList;
    }

这里,我们只关心里面的数据,所以导入的时候并没有关心格式那些,代码旧比较简单,有时候可能会关心格式,甚至关心数据的类型那些,具体处理起来就会麻烦一些。

同时,我们同样会发现,其实两种文件的处理代码还是差不多的。

测试

测试的代码比较简单,就是准备数据,调用方法处理,然后观察结果

    public static void main(String[] args) {
        List<User> userList = new ArrayList<>();
        userList.add(new User(1, "test1"));
        userList.add(new User(2, "test2"));
        userList.add(new User(3, "test3"));
        userList.add(new User(4, "test4"));
        userList.add(new User(5, "test5"));
        userList.add(new User(6, "test6"));
        userList.add(new User(7, "test7"));
        userList.add(new User(8, "test8"));

        PoiXlsxService poiXlsx = new PoiXlsxService();
        File xlsx = poiXlsx.userListToFile(userList);
        PoiXlsService poiXls = new PoiXlsService();
        File xls = poiXls.userListToFile(userList);

        userList = poiXlsx.fileToList(xlsx);
        System.out.println(Arrays.toString(userList.toArray()));
        userList = poiXls.fileToList(xls);
        System.out.println(Arrays.toString(userList.toArray()));
    }

小结

文中演示的只是基本简单的操作,基本的数据导出和导入,具体的操作还有很多奇妙的地方,还需要仔细发现。

© 著作权归作者所有

共有 人打赏支持
阿信sxq

阿信sxq

粉丝 227
博文 83
码字总数 73652
作品 1
成都
后端工程师
私信 提问
Java读取Excel数据:基于Apache POI(一)

版权声明:本文为Zhang Phil原创文章,请不要转载! https://blog.csdn.net/zhangphil/article/details/85302347 Java读取Excel数据:基于Apache POI(一) Java本身不支持直接读取微软的Exc...

zhangphil
2018/12/27
0
0
Java读取和解析Excel数据:基于Apache POI(二)

版权声明:本文为Zhang Phil原创文章,请不要转载! https://blog.csdn.net/zhangphil/article/details/85317882 Java读取和解析Excel数据:基于Apache POI(二) 假设附录1文章中的test.xl...

zhangphil
01/02
0
0
Java程序员从笨鸟到菜鸟之(一百零四)java操作office和pdf文件(二)利用POI实现数据导出excel报表

在上一篇博客中,我们简单介绍了java读取word,excel和pdf文档内容 ,但在实际开发中,我们用到最多的是把数据库中数据导出excel报表形式。不仅仅简单的读取office中的数据.尤其是在生产管理...

长平狐
2012/11/12
1K
0
Android读写SQLite数据库并导出SQLite数据写入到Excel表中

版权声明:本文为Zhang Phil原创文章,请不要转载! https://blog.csdn.net/zhangphil/article/details/86083376 Android读写SQLite数据库并导出SQLite数据写入到Excel表中 需要先引入Apach...

zhangphil
前天
0
0
使用Apache POI读取Excel文件

网上关于介绍Apache POI操作Excel的文章已经很多了,但都讲得比较复杂。poi的API 与实际使用中的Excel很类似,可以说是POI把Excel中的workbook、sheet、cell等对象化了,在实际使用中极易理解...

zlikun
2013/05/13
0
4

没有更多内容

加载失败,请刷新页面

加载更多

rabbitMQ 在spring 的使用

一、准备工作 maven依赖 <dependency>  <groupId>com.rabbitmq</groupId>  <artifactId>amqp-client</artifactId>  <version>4.0.2</version></dependency> <dependency......

狼王黄师傅
昨天
1
0
Android JNI总结

0x01 JNI介绍 JNI是Java Native Interface的缩写,JNI不是Android专有的东西,它是从Java继承而来,但是在Android中,JNI的作用和重要性大大增强。 JNI在Android中起着连接Java和C/C++层的作...

天王盖地虎626
昨天
1
0
大数据教程(11.8)Hive1.2.2简介&初体验

上一篇文章分析了Hive1.2.2的安装,本节博主将分享Hive的体验&Hive服务端和客户端的使用方法。 一、Hive与hadoop直接的关系 Hive利用HDFS存储数据,利用MapReduce查询数据。 二、Hive与传统数...

em_aaron
昨天
3
0
跟我学Spring Cloud(Finchley版)-15-Hystrix监控详解

Hystrix提供了监控Hystrix Command的能力,本节来详细探讨。 监控端点与数据 应用整合Hystrix,同时应用包含spring-boot-starter-actuator 依赖,就会存在一个/actuator/hystrix.stream 端点...

周立_ITMuch
昨天
6
0
day26:shell题

1、 判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor id一行中。 如果其生产商为AuthenticAMD,就显示其为AMD公司; 如果其生产商为GenuineIntel,就显示其为Intel公司; 否则,...

芬野de博客
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部