java POI讀寫excel(項目實際需求)

這幾天因爲工做須要,須要作一個報表比對工具(找出兩張報表的差別)。需求以下html

一、作一個客戶端工具,採用java,能夠不用GUI(考慮到,我目前只懂j2ee相關的技術,其實這個需求用python(python版本)來作是最合適的,但是我目前不會,固然後面我會學習下這們語言)java

二、兩張報表的比隊列須要靈活配置,經過配置文件來控制須要比對的列(能夠是一列,能夠是多列)python

三、須要找出表A中有的一條數據,可是表B中沒有的。或者表B中有的,表A中沒有的。或者表A和表B同時都存在的一條數據,可是裏面的某一些字段不同。git

四、兩張報表的格式可能不同,有可能爲csv,xls,xlsx。兩張報表的列數也是不固定的(這兩張報表能夠是任意的兩張報表)github

五、將比對結果再彙總到一張excel中(格式沒有要求,我這裏默認的是xls)apache

六、主鍵可能爲複合主鍵,比對的報表,可能須要一次比對多組報表(因爲這個需求,是今天才加上的,因此目前代碼還處理這個問題,固然會很快加上)數組

思路一:數據結構

poi1-1

一、採用二維數組爲主要的數據結構。由於,報表的列數不肯定,因此不能構造對象,採用下標來控制每一列xss

二、將A表中的第一行的主鍵,而後搜索表B的主鍵,若是沒搜到記下來,若是搜到了,比較所配置的列看是否相同,若是不一樣記下來,再反搜,表B中的主鍵來搜素表A,若是表B中有的,表A中沒有的,記下來。ide

將記下來的數據重組,再導出excel。

效率:兩張表都是30多列,52行,大概一秒左右比對完導出到excel中。

思路二

poi1-2

一、主要採用了循環加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,請多多指教

相關文章
相關標籤/搜索