实现execl的文件读取和数据处理并按照规则输出到指定的文本文件

251 阅读3分钟

一、题目:

1、读取文件(房源数据.xlsx)格式为excel:

成功的记录写入到Success.txt 文件中;数据重复的记录写入到Repeat.txt中;数据错误的记录写入到Error.txt 中,并记录错误原因。

2、数据的验证规则:

2.1重复的验证(与“房源库.txt” 的房源文件对比):
    a.如果城市名称和房源名称俩个都一样,则视为重复记录;
    b.房源名称匹配的时候,忽略特殊字符。例如:房&5与房5匹配,房11与房_11匹配
2.2数据校验:(错误记录保存到Error.txt 中)
  a.房源价格必须为数字,且不能为空;
  b.深圳房源价格不能低于10万,高于1000万;珠海房源价格不能价格低于5万,高于500万;
  c.其它则为正确数据

二、实现

1、代码解释

使用easyexcel读取房源数据.xlsx中的数据,需要建立house的实体类用于接收数据,以及实现DemoDataListener监听器,返回List<House> list。通过遍历houseNum字符串,使用houseNum.charAt(i)得到每个字符,去除houseNum中的特殊字符。再使用io流读取房源库中的数据,返回List<House> houses。遍历list和houses,比较houseNum与city得到重复数据houseRepeat,去除掉houseList中的重复数据。遍历houseList,房源价格不为数字或者为空的数据,深圳与珠海的房源价格不在范围内的数据放入houseError中,houseList删除houseError。将重复数据,错误数据,成功数据分别写入txt文本中

不多bb,直接上代码、

import com.alibaba.excel.EasyExcel;
import com.jjshome.house.excel.entity.House;
import java.io.File;
import java.util.ArrayList;
import java.util.List;


public class ReadTest {

    public static void main(String[] args) {

        String fileName = "C:\Users\Administrator\Desktop\初级机试题\房源数据.xlsx";
        List<House> list = EasyExcel.read(fileName, House.class, new DemoDataListener()).sheet("Sheet1").doReadSync();


        //忽略特殊字符
        for (House house : list) {
            String houseNum = house.getHouseNum();
            String name = "";
            for (int i = 0; i < houseNum.length(); i++) {
                if (houseNum.charAt(i)!="&".charAt(0) && houseNum.charAt(i)!="_".charAt(0)){
                    name += houseNum.charAt(i);
                    house.setHouseNum(name);
                }
            }
        }

        //读取房源库.txt库中的数据
        TxtUtil readTxt = new TxtUtil();
        List<House> houses = readTxt.read();

        //去除房源库已存在的数据
        List<House> houseList = new ArrayList<>();
        houseList.addAll(list);
        List<House> houseRepeat = new ArrayList<>();  //用来保存重复的数据
        for (House house : list) {
            for (House house1 : houses) {
                
                if (house1.getHouseNum().equals(house.getHouseNum()) && house1.getCity().equals(house.getCity())){
                    houseRepeat.add(house);
                    houseList.remove(house);
                }
            }
        }

        //数据校验
        List<House> houseError = new ArrayList<>(); // 用来保存错误的数据
        for (House house : houseList) {
            Integer integer = null;
            try {
                integer = Integer.valueOf(house.getPrice());
                if (integer ==null){
                    houseError.add(house);
                }
                if ("深圳".equals(house.getCity())){
                    if (integer <10 || integer >1000 ){
                        houseError.add(house);
                    }
                }else if ("珠海".equals(house.getCity())){
                    if (integer <5 || integer >500 ){
                        houseError.add(house);
                    }
                }
            }catch (Exception e){
                houseError.add(house);
                e.printStackTrace();
                continue;
            }

        }

        //将数据存入指定文本中
        File fileError = new File("C:\Users\Administrator\Desktop\初级机试题\Error.txt");
        readTxt.write(houseError,fileError);
        File fileRepeat = new File("C:\Users\Administrator\Desktop\初级机试题\Repeat.txt");
        readTxt.write(houseRepeat,fileRepeat);

        houseList.removeAll(houseError);
        File fileSuccess = new File("C:\Users\Administrator\Desktop\初级机试题\Success.txt");
        readTxt.write(houseList,fileSuccess);

        System.out.println("数据验证完成");


    }
}

txt文本读写的工具类

import com.jjshome.house.excel.entity.House;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class TxtUtil {

    public List<House> read() {
        List<House> houses = new ArrayList<>();

        File file = new File("C:\Users\Administrator\Desktop\初级机试题\房源库.txt");
        if (file.isFile() && file.exists()) {
            try {
                FileInputStream fileInputStream = new FileInputStream(file);
                InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"GBK");
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

                StringBuffer sb = new StringBuffer();
                String text = null;
                while ((text = bufferedReader.readLine()) != null) {
                    String[] split = text.split("\t");
                    if (!"房源名称".equals(split[0])){
                        House house = new House();
                        house.setHouseNum(split[0]);
                        house.setCity(split[1]);
                        houses.add(house);
                        sb.append(text);
                    }

                }

                bufferedReader.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        
        return houses;

    }


    public List<House> write(List<House> houseList , File file) {
        List<House> houses = new ArrayList<>();

        if (file.isFile() && file.exists()) {
            try {

                FileOutputStream fileOutputStream = new FileOutputStream(file);
                OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream,"GBK");
                BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
                bufferedWriter.write("房源名称\t城市\t价格\n");
                for (House house : houseList) {
                    String toString = house.getHouseNum()+"\t"+house.getCity()+"\t"+house.getPrice()+"\n";

                    bufferedWriter.write(toString);
                }

                bufferedWriter.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return houses;

    }
}

EasyExcel 提供的DemoDataListener

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.jjshome.house.excel.entity.House;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;

// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
@Slf4j
public class DemoDataListener extends AnalysisEventListener<House> {
//    private static final Logger LOGGER = LoggerFactory.getLogger(DemoDataListener.class);
    /**
     * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 5;

    public static List<House> list1 = new ArrayList<House>();

    List<House> list = new ArrayList<House>();


    /**
     * 这个每一条数据解析都会来调用
     *
     * @param data
     *            one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @Override
    public void invoke(House data, AnalysisContext context) {
        System.out.println("解析到一条数据:{}"+ JSON.toJSONString(data));
        list.add(data);
    }
    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
//        saveData();
        list1 = list;
        System.out.println("所有数据解析完成!");
    }
}

house实体类

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

@Data
public class House {

    @ExcelProperty("房源名称")
    public String houseNum;
    
    @ExcelProperty("所在区")
    public String city;
    
    @ExcelProperty("房源价格(单位:万)")
    public String price;
    
}

三、自我总结

算是一个比较基础的题了,主要考验easyexcel的使用,io流,异常的处理等基本功。我前前后后差不多花了两个小时才写完,主要的问题是对io流的使用不够熟练,中间读取txt文本时出现了乱码的问题,花了挺长时间才解决。有必要花时间去巩固一下基础了。