• 关于安卓jxl的excel操作(一)


    背景

    app导出excel,读取excel,可能不常见,但是你得会。

    环境

    win10,11
    jdk8+
    as4+

    引入

    本次实战中,使用到了三方库 net.sourceforge.jexcelapi
    详细的引入如下(gradle):

    implementation group: 'net.sourceforge.jexcelapi', name: 'jxl', version: '2.6.12'
    
    • 1

    文末将会放出全部代码

    开发

    这里已经引入了jxl的三方库,该库可以实现excel的读写操作。
    这里,主要实现的是,导出数据生成excel表,读取execl表的数据。

    首先我们要有一个概念,就是excel表内部构造,是现有一个sheet,再有具体的内容!!!

    所以,在生成excel表后,第一步,就是创建一个sheet,然后再在这个sheet里面进行数据操作!
    其实细心一点就会发现,格式是通用的,如下图:
    在这里插入图片描述
    第一行,一般情况下,都是属性的描述,然后第二行,就是数据的填充,诸如此类。
    那么,是不是可以设计一个通用的数据格式,就行数据的通用读写?
    博主这里选择的,是一个List>这样的数据格式,List是对于某个sheet中的所有数据,而HashMap中的key,就是属性,value就是对应的属性值。在填充内容第一行时,做一下特殊处理,就可以把属性写入了,后续只需要index对齐,即可填充全部数据。

    上面的思路,是比较通用的,注意一下数组越界的情况即可!

    好了,梳理了内容填充的思路,还有一个sheet创建,其实也是大同小异的,进行循环创建即可!

    上核心代码

    首先,先有sheet再有内容,第一步,就是创建sheet,代码如下:
    在这里插入图片描述
    可以看到,有个api就是createSheet,这个方法,就是创建一个表的意思。

    创建完表了,那么,就要利用这个WritableSheet对象,进行表数据的写入了。
    代码如下:
    在这里插入图片描述
    这里的逻辑,就是先插入第一行属性数据,后续再插入内容数据,for循环操作,当然有review空间,这里只是基于功能快速实现写的逻辑,实测可以使用!!!

    通过上述的写sheet,写内容,那么,就会把全部的数据写到excel表了?其实还有几个坑,只有做过才会发现!

    (1)Workbook的write()调用时机问题

    如果同一个Workbook多次调用该方法,实测发现,第一次以后,就不会再写入了,直观现象就是,写入的部分逻辑失效,然后代码调用WorkBook.Close方法,会报错。

    (2)写入数据时,格式的设置问题

    示例代码如下:

    sheet.addCell(new Label(col, positionCounter, headInfo.get(col), wcf));
    
    • 1

    其中wcf就是单元格的格式,测试发现,如果不设置单元格格式,写入会没有内容

    以上,就是导出excel的一些流程和注意的坑,下面再说说,读取excel的一些逻辑

    其实如果你实现了导出,同样的,是不是导入数据,也是按照导出数据时候的数据处理,就可以了?没错,这里直接上核心代码:

    try {
                is = new FileInputStream(path);
                workbook = Workbook.getWorkbook(is);
                //读取excel有多少个表
                Sheet[] sheets = workbook.getSheets();
                if (sheets == null || sheets.length == 0) {
                    return new ArrayList<>();
                }
                //单个单元格
                Cell cell;
                List result = new ArrayList<>();
                List headList = new ArrayList<>();
                for (int s = 0; s < sheets.length; s++) {
                    Sheet sheetCache = sheets[s];
                    String sheetName = sheetCache.getName();
                    //获取所有单元格里面的数据
                    ExcelInfoBean exportBean = new ExcelInfoBean(sheetName, new ArrayList<>());
                    int cols = sheetCache.getColumns();
                    int rows = sheetCache.getRows();
                    //逐行获取
                    List> contentList = new ArrayList<>();
                    for (int r = 0; r < rows; r++) {
                        HashMap contentHashMap = new HashMap<>();
                        for (int c = 0; c < cols; c++) {
                            cell = sheetCache.getCell(c, r);
                            String content = cell.getContents();
                            if (r == 0) {
                                //头部数据
                                headList.add(content);
                            } else {
                                //非头部数据
                                contentHashMap.put(headList.get(c), content);
                            }
                        }
                        if (r != 0) {
                            contentList.add(contentHashMap);
                        }
                    }
                    exportBean.setData(contentList);
                    result.add(exportBean);
                }
                return result;
            }
    
    • 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

    本质上,就是获取这个WorkBook,所有表sheet的数量,然后变量sheets,再从sheet中,读取行,列的数据,再写入到你的内存数据中,就可以了!

    下面是所有相关的代码:

    ExcelInfoBean.class

    public class ExcelInfoBean implements Serializable {
    
        //sheet名字--与数据对象名字一致
        private String sheetTitle;
    
        //key属性名,value属性值--excel头,excel值
        private List> data = new ArrayList<>();
    
        public ExcelInfoBean(@NonNull String sheetTitle, List> data) {
            this.sheetTitle = sheetTitle;
            this.data = data;
        }
    
        public String getSheetTitle() {
            return sheetTitle;
        }
    
        public void setSheetTitle(String sheetTitle) {
            this.sheetTitle = sheetTitle;
        }
    
        public List> getData() {
            return data;
        }
    
        public void setData(List> data) {
            this.data = data;
        }
    }
    
    • 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

    ExcelUtils.class

    public class ExcelUtils implements Serializable {
    
        private static final WritableCellFormat wcf;
    
        static {
            WritableFont wf = new WritableFont(WritableFont.createFont("宋体"), 12,
                    WritableFont.NO_BOLD, false);
            wcf = new WritableCellFormat(wf);
            try {
                wcf.setAlignment(jxl.format.Alignment.CENTRE);// 左右居中
                wcf.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);// 上下居中
    //            wcf.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框
    //            wcf.setWrap(true); // 是否换行;
            } catch (WriteException e) {
                e.printStackTrace();
            }
        }
    
        private static class SingleHolder implements Serializable {
            public final static ExcelUtils mInstance = new ExcelUtils();
        }
    
        public static ExcelUtils getInstance() {
            return SingleHolder.mInstance;
        }
    
        /**
         * 生成excel
         *
         * @param beans       一个对象,对应一个表格
         * @param fileAllPath 文件全路径--如/ddd/dd/
         */
        public boolean exportData(String fileAllPath, String fileName, ExcelInfoBean... beans) {
            if (beans == null || beans.length == 0) {
                return true;
            }
            //数据处理
            OutputStream os = null;
            WritableWorkbook wwb = null;
            try {
                File file = new File(fileAllPath);
                if (!file.exists()) {
                    file.mkdirs();
                }
                os = new FileOutputStream(file.getAbsoluteFile() + File.separator + fileName);
                wwb = Workbook.createWorkbook(os);
                for (int i = 0; i < beans.length; i++) {
                    ExcelInfoBean cacheInfo = beans[i];
                    //开始处理数据
                    String sheetName = cacheInfo.getSheetTitle();
                    //建立表
                    WritableSheet sheet = wwb.createSheet(sheetName, i);
                    List> contentList = cacheInfo.getData();
                    if (contentList != null && !contentList.isEmpty()) {
                        //写入数据
                        //第一行为属性头
                        List headInfo = new ArrayList<>();
                        HashMap headMap = contentList.get(0);
                        for (Map.Entry mapCache : headMap.entrySet()) {
                            headInfo.add(mapCache.getKey());
                        }
                        int positionCounter = 0;
                        if (!headInfo.isEmpty()) {
                            for (int col = 0; col < headInfo.size(); col++) {
                                sheet.addCell(new Label(col, positionCounter, headInfo.get(col), wcf));
                            }
                            //写入表头
                            positionCounter += 1;
                        }
                        //写入内容
                        for (int c = 0; c < contentList.size(); c++) {
                            HashMap contentMap = contentList.get(c);
                            if (contentMap != null && !contentMap.isEmpty()) {
                                for (int col = 0; col < headInfo.size(); col++) {
                                    String headInfoCache = headInfo.get(col);
                                    //通过表头,获取数据
                                    String contentValue = contentMap.get(headInfoCache);
                                    //写入到对应的位置
                                    sheet.addCell(new Label(col, positionCounter, contentValue, wcf));
                                }
                                positionCounter += 1;
                            }
                        }
                    }
                }
                //至此写入
                wwb.write();
                return true;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (wwb != null) {
                    try {
                        wwb.close();
                    } catch (IOException | WriteException e) {
                        e.printStackTrace();
                    }
                }
                if (os != null) {
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return false;
        }
    
        /**
         * 读取excel
         */
        public List importData(@NonNull String path) {
            File file = new File(path);
            if (!file.exists()) {
                return new ArrayList<>();
            }
            //读取excel
            InputStream is = null;
            Workbook workbook = null;
            try {
                is = new FileInputStream(path);
                workbook = Workbook.getWorkbook(is);
                //读取excel有多少个表
                Sheet[] sheets = workbook.getSheets();
                if (sheets == null || sheets.length == 0) {
                    return new ArrayList<>();
                }
                //单个单元格
                Cell cell;
                List result = new ArrayList<>();
                List headList = new ArrayList<>();
                for (int s = 0; s < sheets.length; s++) {
                    Sheet sheetCache = sheets[s];
                    String sheetName = sheetCache.getName();
                    //获取所有单元格里面的数据
                    ExcelInfoBean exportBean = new ExcelInfoBean(sheetName, new ArrayList<>());
                    int cols = sheetCache.getColumns();
                    int rows = sheetCache.getRows();
                    //逐行获取
                    List> contentList = new ArrayList<>();
                    for (int r = 0; r < rows; r++) {
                        HashMap contentHashMap = new HashMap<>();
                        for (int c = 0; c < cols; c++) {
                            cell = sheetCache.getCell(c, r);
                            String content = cell.getContents();
                            if (r == 0) {
                                //头部数据
                                headList.add(content);
                            } else {
                                //非头部数据
                                contentHashMap.put(headList.get(c), content);
                            }
                        }
                        if (r != 0) {
                            contentList.add(contentHashMap);
                        }
                    }
                    exportBean.setData(contentList);
                    result.add(exportBean);
                }
                return result;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (workbook != null) {
                    try {
                        workbook.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (is != null) {
                    try {
                        is.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            return new ArrayList<>();
        }
    
    }
    
    • 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
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184

    that’s all----------------------------------------------------------------------------------------------

  • 相关阅读:
    C++学习 --list
    PyCharm创建一个简单的Django项目
    JDBCUtils的使用和事务
    声网,站在物联网的“土壤”里
    数字货币回测准备:下载与清洗全量历史数据
    住宅代理详细介绍——助您快速入门!
    spring boot整合mybatis,mybatis generator ,自定义typhandler
    企业选型OA系统 ,如何选择合适的?
    在Linux服务器上部署Tornado项目
    ​力扣解法汇总934. 最短的桥
  • 原文地址:https://blog.csdn.net/motosheep/article/details/136774581