1

我正在尝试从 csv 文件中的特定位置创建一个列表,而不是括号。

class Person {//
@Parsed
private String name;
@??
private Address address;
@Convert(conversionClass = Emails2.class, args = { "," , "5,6" })
@Parsed
private List<String> emails;
}

.csv 格式:

name,email1,email2,email3,street,number,neighborhood
Maria,ma@gmail.com,ma@hotmail.com,,Regent Street,12,downtown
Ana,ana@gmail.com,a@hotmail.com,,Bird Street,,east side

我需要阅读 csv 文件并创建一个电子邮件列表和一个地址对象。我试图使用@Convert,

public class Emails2 implements Conversion<String, Set<String>> {

    private final String separator;
    private final Set<String> positions;

    public Emails2(String... args) {
        String separator = ",";
        Set<String> positions = null;

        if (args.length == 1) {
            separator = args[0];
        }

        if (args.length == 2) {
            positions = new HashSet<String>();
            String[] posi = args[1].split(",");
            for (String string : posi) {
                positions.add(string);
            }
        }
        this.separator = separator;
        this.positions = positions;
    }

    public Emails2(String separator, Set<String> positions) {
        this.separator = separator;
        this.positions = positions;
    }
//this method is not called, I don't know why
    public Set<String> execute(String input) { //I would like add the list and Address object inside this method to get it done in beanProcessed(...)
        if (input == null) {
            return Collections.emptySet();
        }

        Set<String> out = new TreeSet<String>();
        for (String token : input.split(separator)) {
            for (String word : token.trim().split("\\s")) {
                out.add(word.trim());
            }
        }
        return out;
    }

    public String revert(Set<String> input) {
        return revert(input);
    }

}

我过得怎么样

    public static void main(String[] args) {

            BeanProcessor<Person> rowProcessor = new BeanProcessor<Person>(Person.class) {
                @Override
                public void beanProcessed(Person c, ParsingContext context) {
                    System.out.println(c.getName());

                    String[] positions = context.currentParsedContent().split(","); 
                    System.out.println(positions[5]);
//I'm using fixed position here, I'd like get the position from @Convert or another way by configuration
                    System.out.println(positions[6]);
                    List<String> list = new ArrayList<>();
                    list.add(positions[5]);
                    list.add(positions[6]);
                    c.setEmails(list);
                }

            };

            CsvParserSettings parserSettings = new CsvParserSettings();
            parserSettings.setRowProcessor(rowProcessor);
            parserSettings.setHeaderExtractionEnabled(true);
            CsvParser parser2 = new CsvParser(parserSettings);
            parser2.parse(getReader("/var/lib/cob/test2.csv"));

        }
4

2 回答 2

0

我以另一种方式实现了我想要的,不是我想要的,但它奏效了。我使用 MultiBeanProcessor 并创建了虚拟类(我的老板不会喜欢)来代表我的 csv 职位。

我真正的 csv 有如下标题:

email1,email2,email3,dddcel1,dddcel2,dddcel3,dddcel4,dddtel1,dddtel2,dddtel3,firstName,document,v_atu,ofe_cc,ignore1,bank,agency,ignore2,invoiceNumber,contactPhone,address,neighborhood,zip,city,state

    class Email{
    @Parsed 
    private String email1;
    @Parsed 
    private String email2;
     @Parsed
    private String email3;
    }

class Mobile{
    @Parsed
    private String dddcel1;
    @Parsed
    private String dddcel2;
    @Parsed
    private String dddcel3;
    @Parsed
    private String dddcel4;
}

和 MultiBeanProcessor

 MultiBeanProcessor processor = new MultiBeanProcessor(Customer.class, Address.class, Email.class, Mobile.class, Phone.class) {
            private Customer customer;
            private Address address;
            private Email email;
            private Mobile mobile;
            private Phone phone;

            @Override
            public void beanProcessed(Class<?> beanType, Object beanInstance, ParsingContext context) {

                if (beanType == Customer.class) {
                    customer = (Customer) beanInstance;
                    customer.set_id(UUID.randomUUID().toString());
                    customer.setStatus(CustomerStatusType.PENDING);
                    customer.setDiscountValue(customer.getInvoiceValue() - customer.getTotalValue());
                    customer.setToken(UUID.randomUUID().toString());
                    try {
                        customer.setCreated(new java.text.SimpleDateFormat("yyyy-MM-dd")
                                .parse((new java.text.SimpleDateFormat("yyyy-MM-dd").format(new java.util.Date()))));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }

                    customer.setDomain("???????????");
                    Map<String, String> map = new HashMap<String, String>();
                    map.put("banco", customer.getBank());
                    map.put("agencia", customer.getAgency());
                    customer.setInvoiceDetail(map);

                }

                if (beanType == Address.class) {
                    address = (Address) beanInstance;
                    customer.setAddress(address);
                }

                if (beanType == Email.class) {
                    email = (Email) beanInstance;
                    customer.setEmails(Arrays.asList(email.getEmail1(), email.getEmail2(), email.getEmail3()));
                }

                if (beanType == Mobile.class) {
                    mobile = (Mobile) beanInstance;
                    customer.setMobiles(Arrays.asList(mobile.getDddcel1(), mobile.getDddcel2(), mobile.getDddcel3(), mobile.getDddcel4()));

                }

                if (beanType == Phone.class) {
                    phone = (Phone) beanInstance;
                    customer.setPhones(Arrays.asList(phone.getDddtel1(), phone.getDddtel2(), phone.getDddtel3()));
                }

                if (customer != null && address != null && email != null && mobile != null & phone != null) {
                    System.out.println(customer);//save customer object
                    customer = null;
                    address = null;
                    email = null;
                    phone = null;
                    mobile = null;
                }

            }
        };

我还在测试,我希望它适用于 500k 行:)

于 2017-02-26T02:52:37.703 回答
0

您正在尝试通过自定义转换将多列 ( email1, email2, email3) 的值分配到单个属性 ( Person.emails) 中,但由于转换针对单个字段(或输入的列)而不是整行,因此不支持此操作。

此外,execute不会调用自定义转换中的方法,因为emails输入中没有标题。当您使用注释对属性进行@Parsed注释而不提供要匹配的标头名称时,将使用属性名称本身。如果您将属性从 重命名为emailsemail1您将看到您的转换类将被调用,或者您只需在注释中提供字段名称,如下所示:

@Parsed(field = "email1")
private List<String> emails;

它也会被调用。

我看到您在此处尝试执行的操作,并打开了此问题,以便为此类要求提供更好的支持。

希望这可以帮助。

于 2017-02-25T23:48:56.543 回答