Java解析Excel实例解析

最近有些配置APN的工作,需要将Excel中的信息,配置成Android apns-conf.xml中的样式。 
作为一个程序员,我怎么可能一行行的用眼睛看,然后用手去配置了! 
于是,我决定利用Apache POI的支持库,用java程序解析Excel表, 
然后按指定格式生成输出文件。

这篇博客主要记录一下Java解析Excel的基本方法,结尾附上demo。


首先附上Apache POI库的下载地址Apache POI - Download Release Artifacts, 
选择合适的库后,会自动跳转到镜像地址。 
我的demo是基于poi-3.16-beta2写的,不过并没有使用什么高深接口,因此代码应该是通用的。

导入依赖库后,主要的工作其实就是明白依赖库中定义的Excel对象了,这里盗一张图: 

如图所示: 
每一个Excel文件都将被解析成一个WorkBook对象; 
Excel的每一页都将被解析成一个Sheet对象; 
然后,Excel中的每一行都是一个Row对象, 
每一个单元格都是一个Cell对象。

对这些基本概念有了一些基本了解后,就可以开始上实例了。

如上图所示,为Excel中内容的基本格式,即一些APN需要的信息。 
为了方便我解析,我稍微修改了一些格式,将标题栏中每一项的首字母大写(与Java解析Excel无关)。

Java入口函数如下:

public class MainEntrance {
    public static void main(String[] args) {
        //由于Java解析Excel不可避免的与文件格式耦合
        //因此,我只能写一个特质化的工具,而不是写个模板
        ApnExcelParseTool excelParseTool = new ApnExcelParseTool();

        //传入源文件地址
        excelParseTool.setFilePath("/home/zhangjian/Desktop/all_apn_together.xlsx");

        try {
            //解析Excel得到Workbook对象
            Workbook workbook = excelParseTool.initWorkBook();

            //每一行具体数据,都将变成一个ApnModel
            List<ApnModel> outData = new ArrayList<>();

            if (workbook != null) {
                //将workbook对象,解析成ApnModel
                excelParseTool.parseWorkbook(workbook, outData);
            }

            if (outData.size() > 0) {
                //将所有的ApnModel写入到输出文件中
                new ApnWriteTool().write("/home/zhangjian/Desktop/apns-conf.xml", outData);
            }
        } catch (IOException e) {
            System.out.println(e.toString());
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

整个Java主函数的逻辑还是很简单的。


现在我们看看核心类ApnExcelParseTool中的内容,首先看看获取Workbook相关的代码:

class ApnExcelParseTool {
    private String mFilePath;

    //保存源文件内容
    void setFilePath(String filePath) {
        mFilePath = filePath;
    }

    private static final String SUFFIX_2003 = ".xls";
    private static final String SUFFIX_2007 = ".xlsx";

    Workbook initWorkBook() throws IOException {
        File file = new File(mFilePath);
        InputStream is = new FileInputStream(file);

        Workbook workbook = null;
        //根据后缀,得到不同的Workbook子类,即HSSFWorkbook或XSSFWorkbook
        if (mFilePath.endsWith(SUFFIX_2003)) {
            workbook = new HSSFWorkbook(is);
        } else if (mFilePath.endsWith(SUFFIX_2007)) {
            workbook = new XSSFWorkbook(is);
        }

        return workbook;
    }
....................
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

得到Workbook后,就可以开始进一步解析了:

.......................
    void parseWorkbook(Workbook workbook, List<ApnModel> apnModelList) {
        int numOfSheet = workbook.getNumberOfSheets();

        //依次解析每一个Sheet
        for (int i = 0; i < numOfSheet; ++i) {
            Sheet sheet = workbook.getSheetAt(i);
            parseSheet(sheet, apnModelList);
        }
    }

    //保存需要调用的ApnModel中的方法
    private List<Method> mUsedMethod;

    private void parseSheet(Sheet sheet, List<ApnModel> apnModelList) {
        Row row;

        int count = 0;

        //利用迭代器,取出每一个Row
        Iterator<Row> iterator = sheet.iterator();
        while(iterator.hasNext()) {
            row = iterator.next();

            //由于第一行是标题,因此这里单独处理
            if (count == 0) {
                mUsedMethod = new ArrayList<>();
                parseRowAndFindMethod(row);
            } else {
                //其它行都在这里处理
                parseRowAndFillData(row, apnModelList);
            }

            ++count;
        }
    }

    private void parseRowAndFindMethod(Row row) {
        //利用parseRow处理每一行,得到每个cell中的String
        List<String> rst = parseRow(row);

        String methodName;
        try {
            //根据String得到需要调用的ApnModel中的方法
            //由于自己在ApnModel中定义的方法均是类似setMcc、setMnc等
            //因此才在一开始,将标题栏中每一项大写
            for (String str : rst) {
                methodName = "set" + str;
                //反射拿到method
                mUsedMethod.add(
                        ApnModel.class.getDeclaredMethod(methodName, String.class));
            }
        } catch (NoSuchMethodException e) {
            System.out.println(e.toString());
        }

    }

    //开始解析具体的数据
    private void parseRowAndFillData(Row row, List<ApnModel> apnModelList) {
        //同样利用parseRow得到具体每一行的数据
        List<String> rst = parseRow(row);

        ApnModel apnModel = new ApnModel();

        //这里主要debug一下,避免由于Excel的格式可能不太对
        //使得每一行的数据解析地不太对
        if (mUsedMethod.size() != rst.size()) {
            System.out.println("WTF, size not right");
        } else {
            //利用反射,将数据填充到具体的ApnModel
            try {
                for (int i = 0; i < mUsedMethod.size(); ++i) {
                    mUsedMethod.get(i).invoke(apnModel, rst.get(i));
                }

                //保存到输出结果中
                apnModelList.add(apnModel);
            } catch (Exception e) {
                System.out.println(e.toString());
            }
        }
    }

    //这里是解析每一行的代码
    private List<String> parseRow(Row row) {
        List<String> rst = new ArrayList<>();

        Cell cell;

        //利用迭代器得到每一个cell
        Iterator<Cell> iterator = row.iterator();
        while (iterator.hasNext()) {
            cell = iterator.next();

            //定义每一个cell的数据类型
            cell.setCellType(CellType.STRING);

            //取出cell中的value
            rst.add(cell.getStringCellValue());
        }

        return rst;
    }
.................
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105

以上就是Java解析Excel范例的核心代码了。

之后的工作就是将ApnModel中保存的数据,按照需要的格式写入到输出文件了。 
这部分代码比较粗糙,也与主题无关,就不直接贴到博客上了。

最后的输出结果类似于。与原生的格式一致了: 

这里唯一要注意的是,要保证Excel的格式正确。 
单元格的内容可以是空白的,因此要保证Excel中仅有数据占有了实际的内容。 

如上图所示,数据部分可以空白,但非数据的红色部分就不要有内容了。

最后,demo地址如下: 
https://github.com/ZhangJianIsAStark/ExcelParseDemo 
这里我只上传了源代码,还需要自己配置Apache POI jar包。

版权声明:转载请注明:http://blog.csdn.net/gaugamela/article https://blog.csdn.net/Gaugamela/article/details/60954813
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值