常见数据的解析

其实刚开始是看Excel转数据库这个需求怎么写的,但是看完之后发现,重中之重在于Excel文件的解析,抛去这个知识点

之外,就是一些简单的流操作和文件格式的解析,由于这些都不难,就觉得没有写的必要了,于是。。。就想到总结一下

如何将各种文件解析为javaBean。

1.XML---->javaBean列表

这个之前的博客有专门讲到,这里就不啰嗦了,请戳==>XML文件的解析

2.Excel----->javaBean列表

这个其实分两步:

①首先对Excel文件进行解析,因为表格内容由row*col个方块组成,标题加上真正的数据嘛,所以现在将他们取出来

放到一个List中去,那么这个List的长度是显而易见的

package com.eco;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import jxl.Sheet;
import jxl.Workbook;

public class AnalyseFileUtil {
    public static List excelToList(File file) {
        List list = new ArrayList();
        try {
            InputStream is = new FileInputStream(file.getAbsolutePath());
            // jxl提供的Workbook类
            Workbook wb = Workbook.getWorkbook(is);
            // Excel的页签数量
            int sheet_size = wb.getNumberOfSheets();
            for (int index = 0; index < sheet_size; index++) {
                // 每个页签创建一个Sheet对象
                Sheet sheet = wb.getSheet(index);
                // sheet.getRows()返回该页的总行数
                for (int i = 0; i < sheet.getRows(); i++) {
                    // sheet.getColumns()返回该页的总列数
                    for (int j = 0; j < sheet.getColumns(); j++) {
                        String cellinfo = sheet.getCell(j, i).getContents();
                        list.add(cellinfo);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }
}

不难想象现在拿到的list是个什么造型~~~

②接下来就要对这个很长很长的list进行处理了:

这里呢,又分三步,

第一、新建与Excel标题字段相对应的javaBean,这里为方便起见,将所有成员变量都设置成String类型,代码省略;

第二、写一个利用反射来调用之前javaBean指定Set方法的工具(方法),代码简单,我顺便贴上;

/*
     * 利用反射执行javaBean的指定setter方法
     * 
     * @pram obj javaBean的实例化对象
     * 
     * @pram attr javaBean的成员变量
     * 
     * @pram value 为这个变量赋值
     */
    public static void reflectSet(Object obj, String attr, String value) {
        try {
            Method[] m = obj.getClass().getMethods();
            for (int i = 0; i < m.length; i++) {
                if (("set" + attr).toLowerCase().equals(
                        m[i].getName().toLowerCase())) {
                    m[i].invoke(obj, new Object[] { value });
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

参数:obj(javaBean对应的实例化对象)、attr(你想要调用的setter方法的具体成员变量名称)、vaule(为这个变量赋值)

e.g:

User user =new User();

reflectSet(user,"name","桔子桑");

这样调用了user的setName(String str)方法,使得该user对象的name属性值为“桔子桑”。

第三、将之前Excel导出来的字符串List真正转化为javaBean形式的List,当然长度变成了之前的1/col;

/*
     * 将excel解析所得list转为相应的javaBean列表
     * 
     * @pram input excel解析所得list
     * 
     * @pram col excel的标题字段数量(javaBean的成员变量数目)
     * 
     * excel有4列那么对应的javaBean就有4个对应的成员变量
     */
    public static List excellistToBean(List input, int col, Class cls)
            throws InstantiationException, IllegalAccessException {
        List output = new ArrayList();
        int count = input.size() / col;
        int start;
        int part;
        String val;
        String[] pram = new String[col];
        for (int n = 0; n < col; n++) {
            pram[n] = input.get(n).toString();
        }
        for (int i = 1; i < count; i++) {
            start = i * col;
            Object user = cls.newInstance();
            for (int j = 0; j < col; j++) {
                part = start + j;
                val = input.get(part).toString();
                AnalyseFileUtil.reflectSet(user, pram[j], val);
            }
            output.add(user);
        }
        return output;
    } 

这样就实现了,传进三个参数(input为之前的字符串List,col是成员变量的个数也就是Excel表的标题字段个数,cls是与

javaBean相对应的类类型)返回一个javaBean的List了。

下面看测试结果:

package com.eco;

import java.io.File;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        File file = new File("test1.xls");
        List input = AnalyseFileUtil.excelToList(file);
        List list = AnalyseFileUtil.excellistToBean(input, 4,User.class);//Excel有4列,自然col参数为4
        System.out.println(list);
    }
}

结果显示:

[User [id=1, name=jack, sex=男, age=23], 
User [id=2, name=tom, sex=女, age=24],
User [id=3, name=rose, sex=女, age=34], 
User [id=4, name=eco, sex=男, age=23], 
User [id=5, name=eric, sex=男, age=26], 
User [id=6, name=mseo, sex=女, age=24], 
User [id=7, name=queeen, sex=女, age=21], 
User [id=8, name=rock, sex=男, age=22]]

 3.javaBean----->Excel

这里用到了jxl包和spring包

①建表头方法

/*
     * 创建excel表头
     * 
     * @pram file excel的导出路径
     * 
     * @pram keySortArray 字段排序后的数组,例如:["1","2","3","4"]
     * 
     * @pram titleMap 表头的map,且map的key与keySortArray一一对应
     */
    protected static void createExcelTitle(File file, Object[] keySortArray,
            Map titleMap) {
        if (file == null) {
            throw new IllegalArgumentException("文件不存在,无法创建Excel表格。");
        }

        if (keySortArray == null) {
            throw new IllegalArgumentException("keySortArray 为null,请初始化后在操作。");
        }

        if (titleMap == null) {
            throw new IllegalArgumentException("titleMap 为 null,无法创建。");
        }

        WritableWorkbook book = null;
        try {
            book = Workbook.createWorkbook(file);
            // 生成名为“第一页”的工作表,参数0表示这是第一页
            WritableSheet sheet1 = book.createSheet("sheet1", 0);

            int n = 0;
            // 添加标题行
            Label label = null;
            for (Object keyObj : keySortArray) {
                if (titleMap.containsKey(keyObj)) {
                    label = new Label(n++, 0, titleMap.get(keyObj).toString());
                    sheet1.addCell(label);
                }
            }
        } catch (IOException e) {
            throw new IllegalArgumentException("Excel的Sheet工作簿标题写入失败:"
                    + e.getMessage());
        } catch (RowsExceededException e) {
            throw new IllegalArgumentException("Excel的Sheet工作簿标题写入失败:"
                    + e.getMessage());
        } catch (WriteException e) {
            throw new IllegalArgumentException("Excel的Sheet工作簿标题写入失败:"
                    + e.getMessage());
        } finally {
            try {
                book.write();
                book.close();
                book = null;
            } catch (Exception e) {
                throw new IllegalArgumentException("Excel文件写入失败,可能因为该文件正在被打开中:"
                        + e.getMessage());
            }
        }
    }

②添加表内容方法

/*
     * 生成excel表内容
     * 
     * @pram keySortArray 字段顺序数组
     * 
     * @pram fieldMap 表头map对应的javaBean成员变量map
     * 
     * @list javaBean列表
     * 
     * @pram cls javaBean的类类型
     */
    protected static void createExcelContent(File file, Object[] keySortArray,
            Map fieldMap, List list, Class cls) {
        if (file == null) {
            throw new IllegalArgumentException("文件不存在,无法创建Excel表格。");
        }

        if (keySortArray == null) {
            throw new IllegalArgumentException("keySortArray 为null,请初始化后在操作。");
        }

        if (fieldMap == null) {
            throw new IllegalArgumentException("fieldMap 为 null,无法生成。");
        }
        if (list == null) {
            throw new IllegalArgumentException("数据列表 为 null,无法读取数据。");
        }
        if (cls == null) {
            throw new IllegalArgumentException("Class 为 null,无法进行类的映射关系。");
        }

        WritableWorkbook book = null;
        try {
            // Excel获得文件
            Workbook wb = Workbook.getWorkbook(file);
            // 打开一个文件的副本,并且指定数据写回到原文件
            book = Workbook.createWorkbook(file, wb);
            // 生成名为“第一页”的工作表,参数0表示这是第一页
            WritableSheet sheet1 = book.getSheet("sheet1");

            int cols = 0;
            int rows = 1;
            BeanWrapper bw = null;
            Label label = null;
            for (Object obj : list) {
                bw = new BeanWrapperImpl(cls.cast(obj));
                for (Object keyObj : keySortArray) {
                    if (fieldMap.containsKey(keyObj)) {
                        try {
                            label = new Label(cols++, rows,
                                    obj2Str(bw.getPropertyValue(fieldMap.get(
                                            keyObj).toString())));
                            sheet1.addCell(label);
                        } catch (org.springframework.beans.NotReadablePropertyException ex) {
                            label = new Label(cols, rows, "找不到属性为'"
                                    + fieldMap.get(keyObj) + "'的方法");
                            sheet1.addCell(label);
                        }
                    }
                }
                cols = 0;
                rows++;
            }
        } catch (IOException e) {
            throw new IllegalArgumentException("Excel的Sheet工作簿内容写入失败1:"
                    + e.getMessage());
        } catch (RowsExceededException e) {
            throw new IllegalArgumentException("Excel的Sheet工作簿内容写入失败2:"
                    + e.getMessage());
        } catch (WriteException e) {
            throw new IllegalArgumentException("Excel的Sheet工作簿内容写入失败3:"
                    + e.getMessage());
        } catch (BiffException e) {
            throw new IllegalArgumentException("源Excel文件读取失败4:"
                    + e.getMessage());
        } finally {
            try {
                book.write();
                book.close();
                book = null;
            } catch (Exception e) {
                throw new IllegalArgumentException("Excel文件写入失败,可能因为该文件正在被打开中:"
                        + e.getMessage());
            }
        }
    }

③为以上两个方法提供参数,继而生成excel

/*
     * 将javaBean列表导出到对应的excel
     * 
     * @pram list javaBean列表
     * 
     * @pram field2TitleMap map.put("02", "sname|学生姓名")或者map.put("02", "sname")
     * 前者表示javaBean的sname对应生成表的学生姓名,后者表示javaBean的sname对应生成表的sname
     * 
     * @pram filePath 导出的excel文件目录
     * 
     * @pram cls javaBean的类类型
     */

    public static void listBeanToExcel(List list, Map field2TitleMap,
            String filePath, Class cls) {
        if (list == null) {
            throw new IllegalArgumentException("ListRange 未被初始化");
        }
        if (field2TitleMap == null) {
            throw new IllegalArgumentException("field2TitleMap 未被初始化");
        }
        if (filePath == null) {
            throw new IllegalArgumentException("filePath 未被初始化");
        }
        if (cls == null) {
            throw new IllegalArgumentException("Class 未被初始化");
        }

        Object[] keySortArray = field2TitleMap.keySet().toArray();
        Arrays.sort(keySortArray);

        // javaBean变量名称Map
        Map<Object, String> fieldMap = new HashMap<Object, String>();
        // 字段中文描述Map
        Map<Object, String> titleMap = new HashMap<Object, String>();

        // 初始化字段名称与字段描述信息
        Iterator iter = field2TitleMap.entrySet().iterator();
        String[] valArr;
        Map.Entry entry;
        Object key;
        Object val;
        while (iter.hasNext()) {
            entry = (Map.Entry) iter.next();
            key = entry.getKey();
            val = entry.getValue();

            if (val != null) {
                valArr = (val.toString()).split("\|");
                if (valArr.length == 2) {
                    fieldMap.put(key, valArr[0]);
                    titleMap.put(key, valArr[1]);
                } else {
                    fieldMap.put(key, val.toString());
                    titleMap.put(key, val.toString());
                }
            }
        }

        // 创建Excel文件
        File file = new File(filePath);
        // 创建表头
        createExcelTitle(file, keySortArray, titleMap);
        // 生成文件内容
        createExcelContent(file, keySortArray, fieldMap, list, cls);
    }

④测试

        Map map = new HashMap();
        map.put("01", "id");
        map.put("02", "name");
        map.put("03", "sex");
        map.put("04", "age");
        AnalyseFileUtil.listBeanToExcel(list, map, "test3.xls", User.class);

这样就可以将javaBean列表导出到excel文件(test.xls)了

原文地址:https://www.cnblogs.com/eco-just/p/8586870.html