Проверка и импорт данных из файла Excel

Недавно я разработал модуль, который будет выполнять массовую загрузку для другого содержимого. В основном пользователь загрузит файл Excel, мне придется читать и проверять заголовки excel, а затем каждое значение ячейки для всех столбцов. Я разработал структуру, пожалуйста, подтвердите.

Ниже приведены vo.

Детали заголовка шаблона: Excel для каждого содержимого определяется как шаблон, который будет иметь идентификатор и будет иметь заголовок (заголовок столбца Excel) для каждого шаблона:

public class TemplateHeaderDetails extends BaseVO {
    Integer templateId;
    String templateName;
    public String headerNames;
    String mandatory;
    Integer fieldId;

    public Integer getTemplateId() {
        return templateId;
    }

    public void setTemplateId(Integer templateId) {
        this.templateId = templateId;
    }

    public String getTemplateName() {
        return templateName;
    }

    public void setTemplateName(String templateName) {
        this.templateName = templateName;
    }

    public String getHeaderNames() {
        return headerNames;
    }

    public void setHeaderNames(String headerNames) {
        this.headerNames = headerNames;
    }

    public String getMandatory() {
        return mandatory;
    }

    public void setMandatory(String mandatory) {
        this.mandatory = mandatory;
    }

    public Integer getFieldId() {
        return fieldId;
    }

    public void setFieldId(Integer fieldId) {
        this.fieldId = fieldId;
    }

}

Каждому столбцу заголовка присваивается идентификатор поля, как вы можете видеть в vo выше.

Мы определили правила проверки:

public class Rule extends BaseVO {

    String ruleName;
    Integer ruleId;
    String methodName;
    String className;
    String validationMessage;
    List<String> referenceFields;

    public String getRuleName() {
        return ruleName;
    }
    public void setRuleName(String ruleName) {
        this.ruleName = ruleName;
    }
    public Integer getRuleId() {
        return ruleId;
    }
    public void setRuleId(Integer ruleId) {
        this.ruleId = ruleId;
    }
    public String getMethodName() {
        return methodName;
    }
    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }
    public String getClassName() {
        return className;
    }
    public void setClassName(String className) {
        this.className = className;
    }
    public String getValidationMessage() {
        return validationMessage;
    }
    public void setValidationMessage(String validationMessage) {
        this.validationMessage = validationMessage;
    }
    public List<String> getReferenceFields() {
        return referenceFields;
    }
    public void setReferenceFields(List<String> referenceFields) {
        this.referenceFields = referenceFields;
    }


}

Каждый столбец заголовка (идентификатор поля) будет сопоставлен с правилом

public class RulesMapping extends BaseVO {


    Integer fieldId;
    String referenceField;
    Integer ruleId;
    public Integer sequenceNumber;
    String ruleConfig;
    public Integer getRuleId() {
        return ruleId;
    }
    public void setRuleId(Integer ruleId) {
        this.ruleId = ruleId;
    }
    public  Integer getSequenceNumber() {
        return sequenceNumber;
    }
    public  void setSequenceNumber(Integer sequenceNumber) {
        this.sequenceNumber = sequenceNumber;
    }

    public Integer getFieldId() {
        return fieldId;
    }
    public void setFieldId(Integer fieldId) {
        this.fieldId = fieldId;
    }
    public String getReferenceField() {
        return referenceField;
    }
    public void setReferenceField(String referenceField) {
        this.referenceField = referenceField;
    }
    public String getRuleConfig() {
        return ruleConfig;
    }
    public void setRuleConfig(String ruleConfig) {
        this.ruleConfig = ruleConfig;
    }


}

Ниже приведен код, который будет читать файл Excel, проверять и обновлять базу данных и обновлять excel с комментариями сообщений проверки и успеха.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;




public class BulkUploader {


    private static final String BULKUPLOAD_UPDATE_RECORD = "BULKUPLOAD_UPDATE_RECORD";

    // This will contain module name plus header details
    List<TemplateHeaderDetails>  details = new ArrayList<TemplateHeaderDetails>();

    // template Name to header details(contians column name ,mandatory columns , sequence)
    List<HeaderDetails> headerDetails =null;

    // all key value pair mapping (  holding column name and its respective value per row.
    Map<String,Object>  records =  new HashMap<String,Object>();


    // field ID to rules mapping
    Map<Integer,List<RulesMapping>>  rulesMapping =  new HashMap<Integer,List<RulesMapping>>();


    // Rule id to Rule 
    Map<Integer,Rule>  rules =  new HashMap<Integer,Rule>();


    Map<Integer,List<String>>  errorMessages =  new HashMap<Integer,List<String>>();

    // List of procedure to be executed
    List<SP>  procedureList = new ArrayList<SP>();




    public void setUpData(){



        Map<Integer,String>  spColumnNames =new  TreeMap<Integer,String>();
        spColumnNames.put(1,"BDATE");
        spColumnNames.put(2,"ACTION");
        spColumnNames.put(3,"BBULLETIN_ID");
        spColumnNames.put(4,"BBULLETIN_NO");
        spColumnNames.put(5,"DATATitle");
        spColumnNames.put(6,"DATAStatus");
        spColumnNames.put(7,"DATAIntroduction (Rewritten)");
        spColumnNames.put(8,"Summary");
        spColumnNames.put(9,"Direct Questions To");
        spColumnNames.put(10,"Effective Start Date");
        spColumnNames.put(11,"Tags/Keywords");
        spColumnNames.put(12,"Created Date");
        spColumnNames.put(13,"Creator Name");

        SP sp = new SP();
        sp.setProcedureName("POC_BULK_UPLOAD");
        sp.setColumnSeq(spColumnNames);

        procedureList.add(sp);

    }



    @SuppressWarnings("unchecked")
    public void readExcel() throws IOException, IllegalAccessException, InstantiationException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException{
        FileInputStream file = new FileInputStream(new File("C:\\Data.xlsx"));

        //Get the workbook instance for XLS file
        XSSFWorkbook workbook = new XSSFWorkbook(file);

        //Get first sheet from the workbook
        XSSFSheet sheet = workbook.getSheetAt(0);

        // GET the header row
        Row headerRow = sheet.getRow(0);

        // LIst of headers from excel
        List<String> headers = new ArrayList<String>();
        Iterator<Cell> cells = headerRow.cellIterator();
        while (cells.hasNext()) {
            Cell cell = (Cell) cells.next();
            RichTextString value = cell.getRichStringCellValue();
            headers.add(value.getString());
        }

        // validate the template 
        Object[] headerValidation = validateTempalte(headers );

        // if validation fails then write back the message to user.
        if((Boolean) headerValidation[0]==false){
            List<String> headerValidationMsg = (List<String>) headerValidation[1];
            appendHeaderComments(workbook,sheet,headerValidationMsg,headers);
            return ;
        }

        // Assign a number to header.This is done so that when we reading excel value we can identiy the cell value belongs to which column 
        Map<String,Integer> headerSeqNumber = assignHeaderSeqNumber(headers);


        // 

        //Get iterator to all the rows in current sheet
        int rowNumber=0;
        Iterator<Row> rowIterator = sheet.iterator();
        while (rowIterator.hasNext()) {
            Row row = (Row) rowIterator.next();
            if(rowNumber==0){
                rowNumber++;
                continue;
            }
            System.out.println("Row no "+rowNumber);
            Iterator<String> columnsIterator = headerSeqNumber.keySet().iterator();
            while (columnsIterator.hasNext()) {
                String name = columnsIterator.next();
                System.out.println("Read columnName "+name);
                int cellType=row.getCell(headerSeqNumber.get(name)).getCellType();
                switch (cellType) {
                case Cell.CELL_TYPE_STRING:
                    RichTextString value= row.getCell(headerSeqNumber.get(name)).getRichStringCellValue();
                    String val=value!=null ?Utils.replaceNonAsciiChar(value.getString().trim()):null;
                    val=val.replaceAll(":", "");
                    val=val.replaceAll("'", "");
                    records.put(name,val);
                    break;
                case Cell.CELL_TYPE_NUMERIC:
                    if (DateUtil.isCellDateFormatted(row.getCell(headerSeqNumber.get(name)))) {
                        Date date = row.getCell(headerSeqNumber.get(name)).getDateCellValue(); 
                        records.put(name,Utils.convertDateToString(date, "dd-MMM-yyyy"));
                    }else{
                        double numericVal= row.getCell(headerSeqNumber.get(name)).getNumericCellValue();
                        records.put(name,numericVal);
                    }
                    break;
                case Cell.CELL_TYPE_BLANK:
                    System.err.println(" blank cell type ");
                    records.put(name,null);
                    break;
                default:
                    System.err.println(" NEither string no number "+row.getCell(headerSeqNumber.get(name)).getCellType());
                    System.err.println(" value "+row.getCell(headerSeqNumber.get(name)).getStringCellValue());
                    break;
                }

            }
            // once a row is read validate each cell 
            Object[]  validationResults=validateRecords(records);
            Boolean isDataValid =(Boolean) validationResults[0];

            List<String> vMessages =new ArrayList<String>();
            // if data is valid then update the value in db.
            if (isDataValid) {
                System.out.println(" Valid data sending for upating record");
                String msg = executeProcedure(records);
                vMessages.add(msg);
            }else{
                // if there is validation issues then add the messages to list.
                if(validationResults[1]!=null){
                    vMessages = (List<String>) validationResults[1];
                }
                System.err.println(" data is invalid");
            }
            errorMessages.put(rowNumber, vMessages);
            rowNumber++;
        }

        // append success or failue to excel.
         appendComments(sheet,headers);
         String filePath="C:\\Data.xlsx";
         FileOutputStream fileOut = new FileOutputStream(filePath);
         workbook.write(fileOut);
         fileOut.flush();
         fileOut.close();

    }



    @SuppressWarnings("unchecked")
    private Object[] validateRecords(Map<String,Object> recordValues) throws IllegalAccessException, InstantiationException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException{

        Object[] values = new Object[2];
        List<String>  vMessages = new ArrayList<String>();
        Boolean isDataUploadedValid = true;
        Iterator<TemplateHeaderDetails> columnsIterator = details.iterator();
        while (columnsIterator.hasNext()) {
            TemplateHeaderDetails headerValue = columnsIterator.next();
            String columnName=headerValue.getHeaderNames();
            Object value= recordValues.get(columnName);
            //System.out.println(" columnName "+columnName);
            int fieldId = headerValue.getFieldId();
            List<RulesMapping> ruleList= rulesMapping.get(fieldId);
            //System.out.println(" ruleList "+ruleList);
            if(ruleList!=null){
                for (RulesMapping rulesMapping : ruleList) {
                     String configuration =rulesMapping.getRuleConfig();
                     int sequence =rulesMapping.sequenceNumber;
                     Integer ruleId = rulesMapping.getRuleId();
                     String config = rulesMapping.getRuleConfig();
                     Rule rule =  rules.get(ruleId);
                     String className=rule.getClassName();
                     String methodName=rule.getMethodName();
                     String message = rule.getValidationMessage();
                     List<String> referenceFields = rule.getReferenceFields();
                     Object obj=Class.forName(className).newInstance();
                     //Class<?>[] parameterTypes = Util.getParameterTypes( value,referenceFields,config,message,columnName );
                     Class<?>[] parameterTypes = new Class<?>[5];
                     parameterTypes[0]=Object.class;
                     parameterTypes[1]=List.class;
                     parameterTypes[2]=String.class;
                     parameterTypes[3]=String.class;
                     parameterTypes[4]=String.class;
                     Object[]  validationResults= (Object[]) obj.getClass().getMethod( methodName,parameterTypes).invoke(obj, value,referenceFields,config,message,columnName);
                     Boolean isValidData = (Boolean) validationResults[0];
                     if(!isValidData){
                         isDataUploadedValid=false;
                         vMessages.addAll((List<String>) validationResults[1]);
                     }
                }   
            }

        }
        values[0]=isDataUploadedValid;
        values[1]=vMessages;
        return values;
    }

    // checks if headers from excel matches the headers for template from db based on mandaotry filds.
    private Object[] validateTempalte(List<String> headers){
        Object[] values=new Object[2];
        Boolean isTempateProper=true;
        List<String> errorMessages = new ArrayList<String>();
        //List<HeaderDetails> headerDetails = (List<HeaderDetails>) details.getHeaderDetails();
        for (TemplateHeaderDetails headerDetail : details) {
            if(headerDetail.getHeaderNames().equalsIgnoreCase("ACTION") ||headerDetail.getHeaderNames().equalsIgnoreCase("DATAID")
                    ||headerDetail.getHeaderNames().equalsIgnoreCase("DATASTATUS ID") ||headerDetail.getHeaderNames().equalsIgnoreCase("Department Name")       
                    ||headerDetail.getHeaderNames().equalsIgnoreCase("Status of Record") ||headerDetail.getHeaderNames().equalsIgnoreCase("Description of the Status")
                    ||headerDetail.getHeaderNames().equalsIgnoreCase("Name of the Excel File") ||headerDetail.getHeaderNames().equalsIgnoreCase("Updated By")){
                    continue;
            }

            if(headerDetail.getMandatory().equalsIgnoreCase("Y") && !headers.contains(headerDetail.getHeaderNames())){
                isTempateProper=false;
                errorMessages.add(headerDetail.getHeaderNames() + " column is missing ");
            }
        }
        values[0]=isTempateProper;
        values[1]=errorMessages;
        return values;
    }



    private Map<String,Integer> assignHeaderSeqNumber(List<String> headers){
        Map<String,Integer> headerSeqNumber = new HashMap<String, Integer>();

        int i=0;
        for (String columnName : headers) {
              headerSeqNumber.put(columnName, i);
              i++;
        }

        return headerSeqNumber;

    }


    private String executeProcedure(Map<String, Object> recordValues) {
        try {
            for (SP procedure : procedureList) {
                String query = " call " + procedure.getProcedureName() + " ( ";
                Map<Integer, String> params = procedure.columnSeq;
                Iterator<Integer> keys = params.keySet().iterator();
                int i = 1;
                while (keys.hasNext()) {
                    Integer seq = (Integer) keys.next();
                    if (params.containsKey(seq)) {
                        String columnName = params.get(seq);
                        System.out.println(" columName used in SP "
                                + columnName);
                        if (columnName.equalsIgnoreCase("ACTION")) {
                            query += " 'I' ";
                        } else if (columnName.equalsIgnoreCase("BBULLETIN_ID")) {
                            query += " '1' ";
                        } else if (columnName
                                .equalsIgnoreCase("Department Name")) {
                            query += " 'Compliance' ";
                        } else {
                            query += " '" + recordValues.get(columnName) + "' ";
                        }
                    } else {
                        query += " null ";
                    }
                    if (i <= params.size() - 1) {
                        query += " ,";
                    }
                    i++;
                }
                query += " ,? ,?)";

                ServiceCaller.invokeService(BULKUPLOAD_UPDATE_RECORD, query);
                System.out.println(" complete query " + query);

            }
            return "SUCSSES";
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println(" Errro while upadating record");
            return "FAILED";
        }
    }


    private void appendComments(XSSFSheet sheet ,List<String> headers){
        int rowNumber=0;
        Iterator<Row> rowIterator = sheet.iterator();
        while (rowIterator.hasNext()) {
            Row row = (Row) rowIterator.next();
            if(rowNumber==0){
                Cell headerCell = row.createCell(headers.size());
                headerCell.setCellValue("Comments");    
            }else{
                List<String> vMessages = errorMessages.get(rowNumber);
                StringBuilder builder = new StringBuilder("");
                for (String message : vMessages) {
                    builder.append(message);

                }
                Cell headerCell = row.createCell(headers.size());
                headerCell.setCellValue(builder.toString());    
            }
            rowNumber++;
        }

    }

    private void appendHeaderComments(XSSFWorkbook workbook ,XSSFSheet sheet ,List<String> messages,List<String> headers) throws IOException{

        Row headerRow = sheet.getRow(0);
        Cell headerCell = headerRow.createCell(headers.size());
        headerCell.setCellValue("Comments");

        Row firstRow = sheet.getRow(1);
        Cell commentCell = firstRow.createCell(headers.size());

        String finalMessage=null;
        for (String msg : messages) {
            finalMessage+=msg;
        }
        commentCell.setCellValue(finalMessage);

         String filePath="C:\\Data.xlsx";
         FileOutputStream fileOut = new FileOutputStream(filePath);
         workbook.write(fileOut);
         fileOut.flush();
         fileOut.close();

    }


    //  commnets field for each , combine messages from JAVA,DB.
    private void getRecrodStatus(){

    }



    public List<TemplateHeaderDetails> getDetails() {
        return details;
    }



    public void setDetails(List<TemplateHeaderDetails> details) {
        this.details = details;
    }



    public List<HeaderDetails> getHeaderDetails() {
        return headerDetails;
    }



    public void setHeaderDetails(List<HeaderDetails> headerDetails) {
        this.headerDetails = headerDetails;
    }



    public Map<String, Object> getRecords() {
        return records;
    }



    public void setRecords(Map<String, Object> records) {
        this.records = records;
    }



    public Map<Integer, List<RulesMapping>> getRulesMapping() {
        return rulesMapping;
    }



    public void setRulesMapping(Map<Integer, List<RulesMapping>> rulesMapping) {
        this.rulesMapping = rulesMapping;
    }



    public Map<Integer, Rule> getRules() {
        return rules;
    }



    public void setRules(Map<Integer, Rule> rules) {
        this.rules = rules;
    }



    public Map<Integer, List<String>> getErrorMessages() {
        return errorMessages;
    }



    public void setErrorMessages(Map<Integer, List<String>> errorMessages) {
        this.errorMessages = errorMessages;
    }



    public List<SP> getProcedureList() {
        return procedureList;
    }



    public void setProcedureList(List<SP> procedureList) {
        this.procedureList = procedureList;
    }




}

Просматривайте дизайн и реализацию.

11 голосов | спросил VIckyb 20 Mayam14 2014, 10:03:50

3 ответа


14

Конкатенации строк

Иногда вы используете StringBuilder, а иногда и оператор составного присваивания (+=). Ключ, чтобы отличать, когда использовать то, что это: если вы знаете количество конкатенаций, вы используете +=; если вы этого не сделаете, вы используете StringBuilder (или их слишком много).

Исключения

Вы бросаете много из них, но вы ничего не делаете с этим. Это неправильная обработка ошибок.

Дорожки

Ваш путь к рабочему листу excel жестко запрограммирован, изменив его на то, что пользователь может выбрать (например, передав его в main аргументы).

итераторы

В ваших итераторах есть следующее:

Iterator<Cell> cells = headerRow.cellIterator();
while (cells.hasNext()) {
    Cell cell = (Cell) cells.next();

Так как ваш Iterator определяется как Iterator<Cell>, я не думаю, что вам нужно больше его использовать Cell.

Ошибки ввода

  • validateTempalte
  • isTempateProper
  • SUCSSES
  • Errro при записи upadating
  • getRecrodStatus

Определенные типы

В ваших методах проверки вы возвращаете что-то вроде этого:

values[0]=isTempateProper;
values[1]=errorMessages;

Это ошибка very (когда я видел результат, я не знал, почему вы вдруг выбрали первое значение для Boolean). Вместо этого создайте простой класс, содержащий эти поля

class ValidationResult {
    private Boolean isTemplateProper;
    private List<String> errorMessages;
    // Getters + Constructor
}

Впоследствии это позволит вам изменить

if((Boolean) headerValidation[0]==false)

к

if(!validationResult.isProperTemplate())

И вы избавитесь от уродливого типа Object[].

Побочное действие

Печать данных внутри метода, который не предполагается, является побочным эффектом, которого вы не хотите; пусть методы придерживаются своей цели. Может быть, это отладка?

Форматирование

Добавьте больше пробелов и белых линий! Вы должны never иметь 30 строк кода без одной нитки между ними: он чувствует себя слишком стесненным. Также не забудьте помещать пробелы между составными операторами "Row no "+rowNumber и вызовы методов appendHeaderComments(workbook,sheet,headerValidationMsg,headers);

Магические значения

В readExcel() вы жестко кодируете местоположение файла ("C:\\Data.xlsx) дважды. Hardcoding сам по себе сомнительный, но это еще более склонно к ошибкам. Определите его один раз и используйте его во всем приложении.

Алмазный оператор

Иногда вы его используете, иногда нет. Имейте в виду, что это

List<String> vMessages = new ArrayList<String>();

может быть записано как

List<String> vMessages = new ArrayList<>();

Промежуточные переменные

Внутри внутреннего цикла validateRecords() вы объявляете переменную для каждого rule.something(), но вы используете его только один раз. Это 8 строк кода, которые не нужны, определенно, поскольку вы действительно просто переходите от 2 слов к 1 -> Очень незначительные изменения.

И если я не просмотрю его, я вижу несколько переменных, которые там не используются.

Цикл между значениями

Вы делаете это несколько раз с разными значениями:

headerDetail.getHeaderNames().equalsIgnoreCase("ACTION")

Рассмотрите возможность использования коллекции, которая упростит управление:

String[] headersToSkip = new[] {"ACTION", "DATAID", "DATASTATUS ID", "Department Name" };

for(String header : headersToSkip) {
    if(header.equalsIgnoreCase(headerDetail.getHeaderNames())) {
        continue;
    }
}

Пока мы здесь: почему getHeaderNames() возвращает один String? Сделайте это сингулярным.

Нейминг

Сделайте свои методы и переменные как можно более наглядными; часто это означает, что вы не сокращаете их. Например:

  • assignHeaderSeqNumber => assignHeaderSequenceNumber
  • params => Параметры
  • columnSeq => columnSequence
ответил Jeroen Vannevel 20 Maypm14 2014, 16:30:29
7

AFAICT этот код не о загрузке ; скорее, речь идет об импорте данных из файлов Excel в базу данных после проверки ее с помощью правил, загружаемых где-то (возможно, в одну и ту же базу данных).

Я игнорирую код отладки print, код с комментариями и жестко закодированные имена файлов, поскольку они выглядят как артефакты работы в прогресс.

Архитектура

Первые три класса имеют некоторые специфические проблемы:

  • У них нет конструкторов.
  • У них есть сеттеры и геттеры для каждого поля. Большинство из них, вероятно, не нужны. Сети, в частности, часто бесполезны, потому что многие поля не могут существенно изменить. (templateId, например, возможно, никогда не изменится.)
  • У них нет других методов, хотя части BulkUploader должны быть методами Rule и RulesMapping.
  • Все они происходят из BaseVO, который, как представляется, не имеет никакого отношения к их значениям.

Ничто из этого обычно не было бы хорошим стилем. Я предполагаю, что это сделано, чтобы они могли храниться в какой-то библиотеке баз данных, которая ожидает этот стиль. В этом случае это может быть необходимым злом, но это все еще раздражает.

Классы с «деталями» в их именах являются плохим знаком. TemplateHeaderDetails явно представляет либо шаблон (в этом случае его следует называть Template) или список заголовков, используемых шаблоном (в этом случае его следует называть TemplateHeaders).

TemplateHeaderDetails.mandatory должен быть логическим, а не "Y" /"N".

Если Rule предназначен только для правил проверки, его следует называть ValidationRule. «Правило» настолько неопределенно, что оно неинформативно.

Запись сообщения об успехе или ошибке в файл Excel является нечетной. Пользователь, вероятно, не увидит его там. Лучше оставить файл немодифицированным и сообщить сообщение пользователю другим способом.

Ошибки

Неэкранированные строки

executeProcedure не удаляет строки при построении запроса. Это означает, что ввод, содержащий кавычки, символы новой строки и, возможно, другие специальные символы, не будет импортирован правильно и может создать уязвимость SQL-инъекции. readExcel пытается обойти это, удалив некоторые символы, но это также искажает данные.

Пожалуйста, проверьте данные, содержащие кавычки, символы новой строки, символы, отличные от ASCII, и т. д. Убедитесь, что они импортированы без изменений. Удаление символов неверно.

Данные из предыдущих строк

Если столбец не задан в одной строке (например, поскольку его тип ячейки неизвестен), значение из предыдущей строки (и даже предыдущего файла!) остается. Это связано с тем, что BulkUploader.records повторно используется: каждая строка представлена ​​одной и той же картой.

records используется только в readExcel, поэтому она должна быть локальной переменной. Он представляет собой одну строку, поэтому ее необходимо создать заново для каждой строки.

Упрощения

AFAICT BulkUploader.procedureList всегда имеет один элемент. Таким образом, он должен быть SP, а не List<SP>.

BulkUploader.headerDetails не используется.

Большинство ---- +: = 23 =: + ----, вероятно, не нужны.

BulkUploader до flush является избыточным , Просто позвоните close. (Или используйте блок close, чтобы он был надежно закрыт.)

В настоящее время методы проверки возвращают массив {success, message message}. Это не дает понять, что вход недействителен и импорт не может продолжаться - вызывающий должен помнить, чтобы проверить результат. Было бы яснее, если бы они бросали исключения при неудаче.

В try (...), validateRecords иconfiguration не используются.

Некоторые методы должны быть учтены:

  • Часть sequence, которая преобразует строку в записи в readExcel должен быть отдельным методом (records, называемый rowMap?). Часть, которая преобразует ячейку в запись в Map<String, Object> records = rowMap(row);, также может быть отдельным методом.
  • Часть records, которая находит validateRecords для использования должен быть метод Rule.
  • Часть RulesMapping, которая запускает правило, должна быть методом validateRecords.
  • Часть Rule, которая преобразует значение столбца в строку (со специальными случаями для некоторых столбцов), должна быть отдельным методом ( executeProcedure) литий>

Цикл в parameterString может быть executeProcedure, который обновляет for, чтобы было ясно, что он учитывает итерации:

i

Вы можете создавать массивы в одной строке с помощью инициализаторов массива:

for (int i = 1; keys.hasNext(); ++i)

Class<?>[] parameterTypes = {Object.class, List.class, String.class, String.class, String.class}; Object[] values = {isDataUploadedValid, vMessages}; даже не требуется, потому что вы можете передать классы непосредственно в parameterTypes:

getMethod

Method m = obj.getClass().getMethod(methodName, Object.class, List.class, String.class, String.class, String.class); принимает строки, поэтому нет необходимости преобразовывать строку в код FileInputStream. Просто выполните File.

ответил Anonymous 21 Mayam14 2014, 10:51:21
6

Только некоторые общие мысли.

Являются ли ваше поле package protected по назначению? Предотвратите создание плотной связи ваших компонентов, в то время как вы должны начать в основном с помощью private и только увеличивать видимость там, где это необходимо. С другой стороны, если вы «никогда» не планируете добавлять дополнительные операции к вашему объекту данных, сделайте их общедоступными и пропустите бесполезные геттеры.

Являются ли комментарии только для нас сейчас или являются вашими настоящими комментариями?

// List of procedure to be executed
List<SP>  procedureList = new ArrayList<SP>();

В более позднем случае: добавляет ли это значение читателю? Просто найдите подходящее имя переменной, как вы здесь, и пропустите комментарий.

Некоторые из ваших методов довольно длинные, возможно, вы можете извлечь какой-нибудь метод имен, чтобы улучшить читаемость. Кроме того, уменьшая уровень вложенности таким образом, может упростить поддержку кода.

ответил mheinzerling 20 Maypm14 2014, 12:26:48

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132