2014-02-18 17 views
0

我有具有幾個屬性A類:SuperCSV,Dozer:寫入csv文件。對於對象與列表分爲多個行

class A { 

private String col1; 
private String col2; 
private List<B> bList; 

// setters and getters 
} 

Class B { 
private String b1; 
private String b2; 
//setters and getters 
} 

我試圖寫入使用supercsv和推土機csv文件這一點。

csv應該與列表b列出的元素具有相同數量的行。 並且應該有四列col1,col2(這對於所有行是公用的)和b1,b2從列表在A類B類

目前在映射文件中我有:

<mapping type="one-way" wildcard="false" map-null="true"> 
       <class-a>package.a</class-a> 
       <class-b>org.supercsv.io.dozer.CsvDozerBeanData</class-b> 
..... 
</mapping> 

但它只是將數據映射成一排。如果沒有將其映射到一個更平坦的類中,更好的方法是什麼。 在映射中,可以將它從A類映射到CsvDozerBeanData列表?這會工作嗎?

謝謝。

回答

1

您可以添加關係B返回A?然後,你可以孩子的每一個目錄遍歷具有以下豆映射:

new String[] { "a.col1", "a.col2", "b1", "b2" } 

這裏是你如何使用這樣的例子。請注意嵌套循環遍歷每個A中的每個B

public class DozerTest { 

    @Test 
    public final void test() throws IOException { 
     StringWriter out = new StringWriter(); 
     ICsvDozerBeanWriter writer = new CsvDozerBeanWriter(out, 
       CsvPreference.STANDARD_PREFERENCE); 
     writer.configureBeanMapping(B.class, 
       new String[] { "a.col1", "a.col2", "b1", "b2" }); 

     for (A a : generateData()) { 
      for (B b : a.getbList()) { 
       writer.write(b); 
      } 
     } 
     writer.flush(); 
     System.out.println(out.toString()); 
    } 

    private List<A> generateData() { 
     List<A> data = new ArrayList<A>(); 

     for (int i = 0; i < 3; i++) { 
      A a = new A(); 
      a.setCol1("col1 for a" + i); 
      a.setCol2("col2 for a" + i); 

      B firstB = new B(); 
      firstB.setB1("first b1 for a" + i); 
      firstB.setB2("first b2 for a" + i); 
      firstB.setA(a); 

      B secondB = new B(); 
      secondB.setB1("second b1 for a" + i); 
      secondB.setB2("second b2 for a" + i); 
      secondB.setA(a); 

      a.setbList(Arrays.asList(firstB, secondB)); 
      data.add(a); 
     } 

     return data; 
    } 

} 

此打印:

col1 for a0,col2 for a0,first b1 for a0,first b2 for a0 
col1 for a0,col2 for a0,second b1 for a0,second b2 for a0 
col1 for a1,col2 for a1,first b1 for a1,first b2 for a1 
col1 for a1,col2 for a1,second b1 for a1,second b2 for a1 
col1 for a2,col2 for a2,first b1 for a2,first b2 for a2 
col1 for a2,col2 for a2,second b1 for a2,second b2 for a2 

更新,以解決意見

如果您不能添加的關係,那麼你可以使用CellProcessors(你甚至不需要使用推土機)。我剛剛創建了3個簡單的Cell處理器:

  • ElementAt - 只要抓住在期望指數
  • GetB1元素 - 獲取的B
  • GetB2b1場 - 獲得一個Bb2

在這裏,他們都在行動:

@Test 
public final void test2() throws IOException { 
    StringWriter out = new StringWriter(); 
    ICsvDozerBeanWriter writer = new CsvDozerBeanWriter(out, 
     CsvPreference.STANDARD_PREFERENCE); 
    writer.configureBeanMapping(A.class, 
     new String[] { "col1", "col2", "bList", "bList" }); 

    for (A a : generateData()) { 
     for (int i = 0; i < a.getbList().size(); i++) { 
      CellProcessor[] processors = new CellProcessor[] { null, null, 
       new ElementAt(i, new GetB1()), 
       new ElementAt(i, new GetB2()) }; 
      writer.write(a, processors); 
     } 
    } 
    writer.flush(); 
    System.out.println(out.toString()); 
} 

class GetB1 extends CellProcessorAdaptor { 
    public Object execute(Object value, CsvContext context) { 
     validateInputNotNull(value, context); 
     return ((B) value).getB1(); 
    } 
} 

class GetB2 extends CellProcessorAdaptor { 
    public Object execute(Object value, CsvContext context) { 
     validateInputNotNull(value, context); 
     return ((B) value).getB2(); 
    } 
} 

class ElementAt extends CellProcessorAdaptor { 

    private final int index; 

    public ElementAt(int index) { 
     this.index = index; 
    } 

    public ElementAt(int index, CellProcessor next) { 
     super(next); 
     this.index = index; 
    } 

    public Object execute(Object value, CsvContext context) { 
     validateInputNotNull(value, context); 
     Object element = ((List<?>) value).get(index); 
     return next.execute(element, context); 
    } 

} 

輸出:

col1 for a0,col2 for a0,first b1 for a0,first b2 for a0 
col1 for a0,col2 for a0,second b1 for a0,second b2 for a0 
col1 for a1,col2 for a1,first b1 for a1,first b2 for a1 
col1 for a1,col2 for a1,second b1 for a1,second b2 for a1 
col1 for a2,col2 for a2,first b1 for a2,first b2 for a2 
col1 for a2,col2 for a2,second b1 for a2,second b2 for a2 

附:我不建議提供自己的推土機映射XML,除非您真的必須(並且在這種情況下似乎不需要)。

+0

我不能添加從B到A的映射。它們是外部類。我需要從多個字段派生單個字段,因此我添加了推土機映射XML。 – user2033853

+0

這是很好的解決方案,但我有30個字段可以映射到我的源代碼中。我創建了一個pojo,並將源映射到它,然後使用bean映射器或推土機映射器將pojo寫入CSV。謝謝! – user2033853