java POI读写excel(项目实际需求)

这几天由于工作需要,需要做一个报表比对工具(找出两张报表的差异)。需求如下

1、做一个客户端工具,采用java,可以不用GUI(考虑到,我目前只懂j2ee相关的技术,其实这个需求用python(python版本)来做是最合适的,可是我目前不会,当然后面我会学习下这们语言)

2、两张报表的比队列需要灵活配置,通过配置文件来控制需要比对的列(可以是一列,可以是多列)

3、需要找出表A中有的一条数据,但是表B中没有的。或者表B中有的,表A中没有的。或者表A和表B同时都存在的一条数据,但是里面的某一些字段不一样。

4、两张报表的格式可能不一样,有可能为csv,xls,xlsx。两张报表的列数也是不固定的(这两张报表可以是任意的两张报表)

5、将比对结果再汇总到一张excel中(格式没有要求,我这里默认的是xls)

6、主键可能为复合主键,比对的报表,可能需要一次比对多组报表(由于这个需求,是今天才加上的,所以目前代码还处理这个问题,当然会很快加上)

思路一:

java POI读写excel(项目实际需求)_第1张图片

1、采用二维数组为主要的数据结构。因为,报表的列数不确定,所以不能构造对象,采用下标来控制每一列

2、将A表中的第一行的主键,然后搜索表B的主键,如果没搜到记下来,如果搜到了,比较所配置的列看是否相同,如果不同记下来,再反搜,表B中的主键来搜素表A,如果表B中有的,表A中没有的,记下来。

将记下来的数据重组,再导出excel。

效率:两张表都是30多列,52行,大概一秒左右比对完导出到excel中。

思路二

poi1-2

1、主要采用了循环加map的方式,再比较是否有相等行的时候,直接用,表A的mapA.get(mapB.get("key"))如果数据不为空,说明在表A中有数据和表B匹配,这里的get有效的减少了一次循环。利用了map.get的方法速度更快。其他的。但是主要逻辑,还是如思路相同

接下来贴出,处理这个需求的主要代码。贴出代码的目的,主要是希望各位网友看到后,能够给指点一二,我这代码,肯定还需要优化,重构。或者说换思路。当然你有什么想法,通过评论,或者邮件告诉我。谢谢

ReadCSVExcel方法

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
 
import au.com.bytecode.opencsv.CSVReader;
 
import com.qly.report.operate.facade.IReadExcel;
 
public class ReadCsvImpl  implements IReadExcel{
    static String qlyStringArr[][] = new String[1000][1000];
    static String otherStringArr[][] = new String[1000][1000];
    static Map<String,Integer > qlycontent = new HashMap<String,Integer >();
    static Map<String,Integer > othercontent = new HashMap<String,Integer >();
 
    @Override
    public Map<String, Object> readExcel(String path, String flag) {
        CSVReader reader = null;
        // 取特定列放到集合
        try {
            InputStream ins = new FileInputStream(new File(path));
            InputStreamReader in = new InputStreamReader(ins, "gbk");
            reader = new CSVReader(in);
            int len = reader.readNext().length;
            String nextline[];
            int counter = 0;
            // 将不同的来源的csv文件分别存放到不同的二维数组中
            if ("qly".equals(flag)) {
                Map<String, Object> qlyMap = new HashMap<String, Object>();
                while ((nextline = reader.readNext()) != null) {
                    for (int i = 0; i < len; i++) {
                        qlyStringArr[counter][i] = nextline[i];
                    }
                    counter++;
                }
                qlycontent.put("colNum", len);
                qlycontent.put("rowNum", counter);
                qlyMap.put("qlyStringArr", qlyStringArr);
                qlyMap.put("qlycontent", qlycontent);
                return qlyMap;
            }
 
            if ("other".equals(flag)) {
                Map<String, Object> otherMap = new HashMap<String, Object>();
                while ((nextline = reader.readNext()) != null) {
                    for (int i = 0; i < len; i++) {
                        otherStringArr[counter][i] = nextline[i];
                    }
                    counter++;
                }
                othercontent.put("colNum", len);
                othercontent.put("rowNum", counter);
                otherMap.put("othercontent", othercontent);
                otherMap.put("otherStringArr", otherStringArr);
                return otherMap;
            }
 
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
 
}

&#160;

ReadXlsExcel 方法

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
 
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
import com.qly.report.operate.facade.IReadExcel;
import com.qly.report.util.ReportUtil;
 
public class ReadXlsImpl   implements IReadExcel{
 
    public static HSSFWorkbook wb = null;
    public static HSSFSheet hssfSheet =null;
    public static HSSFRow hssfRow = null;
    public static XSSFWorkbook xb = null;
    public static XSSFSheet xssfSheet =null;
    public static XSSFRow xssfRow =null;
    public static String qlyStringArr[][] = new String[1000][1000];
    public  static String otherStringArr[][] = new String[1000][1000];
    static Map<String,Integer > qlycontent = new HashMap<String,Integer >();
    static Map<String,Integer > othercontent = new HashMap<String,Integer >();
    @SuppressWarnings({ "deprecation" })
    @Override
    public Map<String ,Object> readExcel(String path, String flag) {
        int counter = 0;
        try {
            InputStream is = new FileInputStream(new File(path));
 
            wb = new HSSFWorkbook(is);
            hssfSheet = wb.getSheetAt(0);
            // 得到总行数
            int rowNum = hssfSheet.getLastRowNum();
            hssfRow = hssfSheet.getRow(1);
 
            int colNum = hssfRow.getPhysicalNumberOfCells();
            // 正文内容应该从第二行开始,第一行为表头内容
            if("qly".equals(flag)){
                Map<String,Object>qlyMap = new HashMap<String, Object>();
                for (int i = 1; i < rowNum; i++) {
                    hssfRow = hssfSheet.getRow(i);
                    counter = 0;
                    while (counter < colNum) {
                        qlyStringArr[i][counter] = get2003StringCellValue(
                                hssfRow.getCell((short)counter)).trim();
                        counter++;
                    }
                }
                qlycontent.put("colNum", counter);
                qlycontent.put("rowNum", rowNum);
                qlyMap.put("qlyStringArr", qlyStringArr);
                qlyMap.put("qlycontent", qlycontent);
                return  qlyMap;
            }
            if("other".equals(flag)){
                Map<String,Object>otherMap = new HashMap<String, Object>();
                for (int i =1; i < rowNum; i++) {
                    hssfRow = hssfSheet.getRow(i);
                    counter = 0;
                    while (counter < colNum) {
                        otherStringArr[i][counter] = get2003StringCellValue(hssfRow.getCell((short) counter)).trim();
                         
                        counter++;
                    }
                }
                othercontent.put("colNum", counter);
                othercontent.put("rowNum", rowNum);
                otherMap.put("othercontent", othercontent);
                otherMap.put("otherStringArr", otherStringArr);
                return otherMap;
            }
     
 
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }   
        return null;
    }
    private static String get2003StringCellValue(HSSFCell cell) {
        String strCell = "";
         
        if (null == cell) {
            return "";
        }
        switch (cell.getCellType()) {
        case HSSFCell.CELL_TYPE_STRING:
            strCell = cell.getStringCellValue();
            break;
        case HSSFCell.CELL_TYPE_NUMERIC:
            //使用DecimalFormat类对科学计数法格式的数字进行格式化
            DecimalFormat df = new DecimalFormat("#");
            String str = String.valueOf(cell.getNumericCellValue());
            if(ReportUtil.isNumber(str)){
                strCell =  df.format(cell.getNumericCellValue());
            }else{
                strCell = str;
            }
             
            break;
        case HSSFCell.CELL_TYPE_BOOLEAN:
             
            strCell = String.valueOf(cell.getBooleanCellValue());
            break;
        case HSSFCell.CELL_TYPE_BLANK:
            strCell = "";
            break;
        default:
            strCell = "";
            break;
        }
        if (strCell.equals("") || null == strCell) {
            return "";
        }
        return strCell;
 
    }
 
}

&#160;

ReadXlsxExcel方法

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
 
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
import com.qly.report.operate.facade.IReadExcel;
import com.qly.report.util.ReportUtil;
 
public class ReadXlsxImpl implements IReadExcel {
    public static HSSFWorkbook wb = null;
    public static HSSFSheet hssfSheet =null;
    public static HSSFRow hssfRow = null;
    public static XSSFWorkbook xb = null;
    public static XSSFSheet xssfSheet =null;
    public static XSSFRow xssfRow =null;
    public static String qlyStringArr[][] = new String[1000][1000];
    public  static String otherStringArr[][] = new String[1000][1000];
    static Map<String,Integer > qlycontent = new HashMap<String,Integer >();
    static Map<String,Integer > othercontent = new HashMap<String,Integer >();
    @Override
    public Map<String,Object> readExcel(String path, String flag) {
        int counter = 0;
        try {
            InputStream is = new FileInputStream(new File(path));
 
            xb = new XSSFWorkbook(is);
            xssfSheet = xb.getSheetAt(0);
            // 得到总行数
            int rowNum = xssfSheet.getLastRowNum();
            xssfRow = xssfSheet.getRow(1);
 
            int colNum = xssfRow.getPhysicalNumberOfCells();
            // 正文内容应该从第二行开始,第一行为表头内容
            if("qly".equals(flag)){
                Map<String,Object>qlyMap = new HashMap<String, Object>();
                for (int i = 1; i < rowNum; i++) {
                    xssfRow = xssfSheet.getRow(i);
                    counter = 0;
                    while (counter < colNum) {
                        qlyStringArr[i][counter] = get2007StringCellValue(
                                xssfRow.getCell((short) counter)).trim();
                        counter++;
                    }
                }
                qlycontent.put("colNum", counter);
                qlycontent.put("rowNum", rowNum);
                qlyMap.put("qlyStringArr", qlyStringArr);
                qlyMap.put("qlycontent", qlycontent);
                return  qlyMap;
            }
            if("other".equals(flag)){
                Map<String,Object>otherMap = new HashMap<String, Object>();
                for (int i = 1; i < rowNum; i++) {
                    xssfRow = xssfSheet.getRow(i);
                    counter = 0;
                    while (counter < colNum) {
                        otherStringArr[i][counter] = get2007StringCellValue(
                                xssfRow.getCell((short) counter)).trim();
                        counter++;
                    }
                }
                othercontent.put("colNum", counter);
                othercontent.put("rowNum", rowNum);
                otherMap.put("othercontent", othercontent);
                otherMap.put("otherStringArr", otherStringArr);
                return otherMap;
            }
             
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    private static String get2007StringCellValue(XSSFCell cell) {
        String strCell = "";
        if (null == cell) {
            return "";
        }
        switch (cell.getCellType()) {
        case XSSFCell.CELL_TYPE_STRING:
            strCell = cell.getStringCellValue();
            break;
        case XSSFCell.CELL_TYPE_NUMERIC:
            //使用DecimalFormat类对科学计数法格式的数字进行格式化
             
            DecimalFormat df = new DecimalFormat("#");
            String str = String.valueOf(cell.getNumericCellValue());
            if(ReportUtil.isNumber(str)){
                strCell =  df.format(cell.getNumericCellValue());
            }else{
                strCell = str;
            }
             
            break;
        case XSSFCell.CELL_TYPE_BOOLEAN:
            strCell = String.valueOf(cell.getBooleanCellValue());
            break;
        case XSSFCell.CELL_TYPE_BLANK:
            strCell = "";
            break;
        default:
            strCell = "";
            break;
        }
        if (strCell.equals("") || null == strCell) {
            return "";
        }
        return strCell;
 
    }
 
}

全部代码在这里,github,请多多指教

你可能感兴趣的:(java POI读写excel(项目实际需求))