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

背景

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

环境

win10,11

jdk8+

as4+

引入

本次实战中,使用到了三方库 net.sourceforge.jexcelapi

详细的引入如下(gradle):

复制代码
implementation group: 'net.sourceforge.jexcelapi', name: 'jxl', version: '2.6.12'

文末将会放出全部代码

开发

这里已经引入了jxl的三方库,该库可以实现excel的读写操作。

这里,主要实现的是,导出数据生成excel表,读取execl表的数据。

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

所以,在生成excel表后,第一步,就是创建一个sheet,然后再在这个sheet里面进行数据操作!

其实细心一点就会发现,格式是通用的,如下图:

第一行,一般情况下,都是属性的描述,然后第二行,就是数据的填充,诸如此类。

那么,是不是可以设计一个通用的数据格式,就行数据的通用读写?

博主这里选择的,是一个List<HashMap<String,String>>这样的数据格式,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));

其中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<ExcelInfoBean> result = new ArrayList<>();
            List<String> 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<HashMap<String, String>> contentList = new ArrayList<>();
                for (int r = 0; r < rows; r++) {
                    HashMap<String, String> 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;
        }

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

下面是所有相关的代码:

ExcelInfoBean.class

复制代码
public class ExcelInfoBean implements Serializable {

    //sheet名字--与数据对象名字一致
    private String sheetTitle;

    //key属性名,value属性值--excel头,excel值
    private List<HashMap<String, String>> data = new ArrayList<>();

    public ExcelInfoBean(@NonNull String sheetTitle, List<HashMap<String, String>> data) {
        this.sheetTitle = sheetTitle;
        this.data = data;
    }

    public String getSheetTitle() {
        return sheetTitle;
    }

    public void setSheetTitle(String sheetTitle) {
        this.sheetTitle = sheetTitle;
    }

    public List<HashMap<String, String>> getData() {
        return data;
    }

    public void setData(List<HashMap<String, String>> data) {
        this.data = data;
    }
}

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<HashMap<String, String>> contentList = cacheInfo.getData();
                if (contentList != null && !contentList.isEmpty()) {
                    //写入数据
                    //第一行为属性头
                    List<String> headInfo = new ArrayList<>();
                    HashMap<String, String> headMap = contentList.get(0);
                    for (Map.Entry<String, String> 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<String, String> 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<ExcelInfoBean> 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<ExcelInfoBean> result = new ArrayList<>();
            List<String> 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<HashMap<String, String>> contentList = new ArrayList<>();
                for (int r = 0; r < rows; r++) {
                    HashMap<String, String> 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<>();
    }

}

that's all----------------------------------------------------------------------------------------------

相关推荐
Frank_HarmonyOS4 小时前
Android MVVM(Model-View-ViewModel)架构
android·架构
l1t7 小时前
DeepSeek辅助编写的将xlsx格式文件中sheet1.xml按需分别保留或去掉标签的程序
xml·python·excel·wps·xlsx
新子y8 小时前
【操作记录】我的 MNN Android LLM 编译学习笔记记录(一)
android·学习·mnn
lincats9 小时前
一步一步学习使用FireMonkey动画(1) 使用动画组件为窗体添加动态效果
android·ide·delphi·livebindings·delphi 12.3·firemonkey
想想吴10 小时前
Android.bp 基础
android·安卓·android.bp
写点啥呢17 小时前
Android为ijkplayer设置音频发音类型usage
android·音视频·usage·mediaplayer·jikplayer
揭老师高效办公19 小时前
在Excel和WPS表格中为多个数字同时加上相同的数值
excel·wps表格
coder_pig1 天前
🤡 公司Android老项目升级踩坑小记
android·flutter·gradle
死就死在补习班1 天前
Android系统源码分析Input - InputReader读取事件
android
死就死在补习班1 天前
Android系统源码分析Input - InputChannel通信
android