Apache POI 实现对 Excel 文件读写

简介:

1. Apache POI 简介

     Apache POI是Apache软件基金会的开放源码函式库。

     提供API给Java应用程序对Microsoft Office格式档案读和写的功能。

     老外起名字总是很谦虚,POI为(Poor Obfuscation Implementation)的首字母缩写,意为“可怜的模糊实现”。

     如果你查看过 Apache 开源库中的任意项目的源码,你会发现恰到好处的设计模式、高内聚低耦合的模块关系、

     到位的接口抽象、优雅的实现方式,这样的一些特点。

     o(︶︿︶)o 唉 需要多严谨的思维、多大的代码实现量,多少项目的设计积累,才能达到那样的高度?

     POI 中主要提供的读写 Microsoft Office 功能点如下:

  •  HSSF -- 提供读写Microsoft Excel格式档案的功能。
  •  XSSF -- 提供读写Microsoft Excel OOXML格式档案的功能。
  •  HWPF -- 提供读写Microsoft Word格式档案的功能。
  •  HSLF -- 提供读写Microsoft PowerPoint格式档案的功能。
  •  HDGF -- 提供读写Microsoft Visio格式档案的功能。

     本文借一次使用POI 实现读写 Excel 的过程,记述其中具体POI运用的方式。

     由搜索引擎点进来的同学,上面这一句话就是本文的主旨句。若能解决你问题,请往下细看。

     项目中使用的是最新的 poi-3.14-20160307.jar,百度云地址:http://pan.baidu.com/s/1bnWFWg3 密码: kame

     Oschina  收录地址:https://www.oschina.net/p/poi

     官方 Demo : http://poi.apache.org/spreadsheet/examples.html#hssf-only

2.一点点实现前的设计

     因项目比较大,下面为单独新建工程后的例子。

   

3.POI 写 Excel

     上图左侧用例图为 POI 写 Excel

    a.getExcelData: 获取需要输出到Excel数据,这里的数据获取可以是从持久层,页面展示层......

      (例子中的数据为Mysql自有数据库中表help_categroy 表记录),其中的 JavaBean建立 与 数据库获取的过程这里就不说了。

      获取数据的数据类型是这样的 List<HelpCategory>    

     b.POI Write Workbook:这里才是关键的地方,使用POI 将数据实例化为 HSSFWorkbook。核心代码如下:

  Core Code

     获取JavaBean字段值作为表头,并设置表头的样式:

复制代码
        HSSFRow row = sheet.createRow(0);
        HSSFCell cell;
        HelpCategory category = new HelpCategory();
        Field[] fields = category.getClass().getDeclaredFields();
        for (int j = 0; j < fields.length; j++) {
            cell = row.createCell(j);
            cell.setCellValue(fields[j].getName());
            cell.setCellStyle(this.textAlignCenter);
        }
复制代码

     获取JavaBean HelpCategory 中字段的值填充到对应的表格中,并设置样式:

复制代码
     for (int i = 0; i < helpCategories.size(); i++) {
            category = helpCategories.get(i);
            row = sheet.createRow(i + 1);
            for (int k = 0; k < fields.length; k++) {
                Field field = fields[k];
                Object o = invokeGet(category, field.getName());
                cell = row.createCell(k);
                cell.setCellValue(o != null ? o.toString() : "");
                cell.setCellStyle((k == 0 || k == 1) ? this.textAlignCenter : this.textAlignLeft);
            }
        }
复制代码

      这里面用的了一点反射的东西,来获取javaBean属性的值。

      如果你觉得反射的效率有点差劲,可以自己构造一个Map数据集合,同样能达到这样的效果。

复制代码
  private Object invokeGet(Object o, String fieldName) {
        Method method = getGetMethod(o.getClass(), fieldName);
        try {
            return method.invoke(o, new Object[0]);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private Method getGetMethod(Class objectClass, String fieldName) {
        StringBuilder sb = new StringBuilder();
        sb.append("get");
        sb.append(fieldName.substring(0, 1).toUpperCase());
        sb.append(fieldName.substring(1));
        try {
            return objectClass.getMethod(sb.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
复制代码

        同样你可以设置表格样式、边框样式:

复制代码
    private void createSheetStyle(HSSFWorkbook _workbook, HSSFSheet _sheet) {
        // 设置表字体
        HSSFFont font10 = _workbook.createFont();
        font10.setFontHeightInPoints((short) 12);
        font10.setFontName("黑体");
        // 设置表样
        this.textAlignCenter = getCellStyle(_workbook, font10, HSSFCellStyle.ALIGN_CENTER);
        this.textAlignLeft = getCellStyle(_workbook, font10, HSSFCellStyle.ALIGN_LEFT);
        // 设置列宽
        _sheet.setColumnWidth(0, 4000);
        _sheet.setColumnWidth(1, 4000);
        _sheet.setColumnWidth(2, 10000);
        _sheet.setColumnWidth(3, 10000);
    }
复制代码

   上面的样式设置,如果还满足不了你的功能需求,更多的设置请参考博客:

   http://langhua9527.iteye.com/blog/388005

   http://blog.csdn.net/tolcf/article/details/48346697

4.POI 读 Excel

      上图左侧用例图为 POI 写 Excel

      a.getExcleFile:获取要读取的Excel文件...这里就不说了。(注意:判断获取的文件后缀名)

复制代码
        String fileName = excel.getName();
        int iIndex = fileName.lastIndexOf(".");
        String ext = (iIndex < 0) ? "" : fileName.substring(iIndex + 1).toLowerCase();
        if (!"xls,xlsx".contains(ext) || "".contains(ext)) {
            System.out.println("文件类型不是EXCEL!");
        }
复制代码

      b.POI Read Workbook:这里就是重点啦,使用POI读取Excel文件,解析并进行保存到你自己数据类型当中。

复制代码
           ArrayList<HelpCategory> categories = new ArrayList<>();
        try {
            POIFSFileSystem poifsFileSystem = new POIFSFileSystem(new FileInputStream(excel));
            HSSFWorkbook workbook = new HSSFWorkbook(poifsFileSystem);
            HSSFSheet sheet = workbook.getSheetAt(0);

            HelpCategory category = new HelpCategory();
            Field[] declaredField = category.getClass().getDeclaredFields();
            for (int k = 1; k <= sheet.getLastRowNum(); k++) {
                HSSFRow row = sheet.getRow(k);
                category = new HelpCategory();
                for (int j = 0; j < declaredField.length; j++) {
                    HSSFCell cell = row.getCell(j);
                    invokeSet(category, declaredField[j].getName(), cell.getStringCellValue());
                }
                categories.add(category);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
复制代码

       上面也同样用到了一些反射的东西,这里获取JavaBean 的set方法,来设置具体的属性。

复制代码
   public void invokeSet(Object o, String fieldName, Object value) {
        Method method = getSetMethod(o.getClass(), fieldName);
        try {
            method.invoke(o, new Object[]{value});
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Method getSetMethod(Class objectClass, String fieldName) {
        try {
            Class[] parameterTypes = new Class[1];
            Field field = objectClass.getDeclaredField(fieldName);
            parameterTypes[0] = field.getType();
            StringBuffer sb = new StringBuffer();
            sb.append("set");
            sb.append(fieldName.substring(0, 1).toUpperCase());
            sb.append(fieldName.substring(1));
            Method method = objectClass.getMethod(sb.toString(), parameterTypes);
            return method;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
复制代码

      上述例子仅当作抛砖引玉之用,项目中的具体需求随时都有其他的变化。

     如获取数据的途径可能是多表联合查询或者是展现层、结果需要进行其他运算、写Excel表格样式的变化........

      但熟悉具体核心读写实现,已不变应万变,可为上将。

     本文转自Orson博客园博客,原文链接:http://www.cnblogs.com/java-class/p/5255024.html,如需转载请自行联系原作者

相关文章
|
18小时前
|
easyexcel Java Apache
EasyExcel导入的时候报错Caused by: java.lang.NoClassDefFoundError: org/apache/poi/poifs/filesystem/File
EasyExcel导入的时候报错Caused by: java.lang.NoClassDefFoundError: org/apache/poi/poifs/filesystem/File
|
23天前
|
Java API Spring
集成EasyPoi(一个基于POI的Excel导入导出工具)到Spring Boot项目中
集成EasyPoi(一个基于POI的Excel导入导出工具)到Spring Boot项目中
72 1
|
1月前
|
XML Java 测试技术
《手把手教你》系列技巧篇(六十七)-java+ selenium自动化测试 - 读写excel文件 - 中篇(详细教程)
【6月更文挑战第8天】本文介绍了Java中操作Excel的工具,包括POI和JXL。POI支持处理Office 2003及以下的OLE2格式(.xls)和2007以上的OOXML格式(.xlsx)。而JXL只能处理2003版本的Excel文件。文章详细讲解了如何下载和使用JXL库,并给出了一个简单的Java代码示例,展示如何读取2003版Excel文件中的数据。在实际项目中,由于JXL对新版本Excel的支持限制,通常推荐使用POI。
38 5
|
1月前
|
Java 测试技术 Apache
《手把手教你》系列技巧篇(六十八)-java+ selenium自动化测试 - 读写excel文件 - 下篇(详细教程)
【6月更文挑战第9天】本文介绍了如何使用Java处理Excel文件中的不同数据类型,包括日期、数字、布尔值和标签(常规字符串)。文章提供了两个示例,分别使用JXL库和Apache POI库来读取Excel文件。
23 1
|
1月前
|
C#
【C#】C#读写Excel文件
【C#】C#读写Excel文件
25 1
|
1月前
|
Java 测试技术 Apache
《手把手教你》系列技巧篇(六十六)-java+ selenium自动化测试 - 读写excel文件 - 上篇(详细教程)
【6月更文挑战第7天】本文介绍了在Java自动化测试中如何操作Excel数据。文章提到了当测试数据存储在Excel文件时,可以使用Apache的POI库来读写Excel。POI提供了对OLE2(.xls)和OOXML(.xlsx)格式的支持,比JXL库功能更全面。文章还详细讲解了如何下载和添加POI库到项目中,以及准备测试用的Excel文件。最后,给出了一个简单的Java代码示例,演示如何读取Excel文件的内容。
31 1
|
16天前
|
easyexcel Java API
Apache POI与easyExcel:Excel文件导入导出的技术深度分析
Apache POI与easyExcel:Excel文件导入导出的技术深度分析
|
19天前
|
Java API Apache
Apache POI(Poor Obfuscation Implementation
Apache POI(Poor Obfuscation Implementation
11 0
|
2月前
|
前端开发 Java
基于Java爬取微博数据(二) 正文长文本+导出数据Excel
【5月更文挑战第12天】基于Java爬取微博数据,正文长文本+导出数据Excel
|
24天前
|
easyexcel Java API
SpringBoot集成EasyExcel 3.x:高效实现Excel数据的优雅导入与导出
SpringBoot集成EasyExcel 3.x:高效实现Excel数据的优雅导入与导出
89 1