2015-11-18 47 views
1

我需要解析來自給定文件夾的幾個csv文件。由於每個csv具有不同的列,因此每個csv在DB中都有單獨的表格。我需要知道使用Spring批解析幾個csv文件

  • Spring批處理是否提供掃描給定文件夾的任何機制,然後我可以將這些文件逐個傳遞給讀者。
  • 正如我試圖使讀者/寫作者通用,是否有可能只獲取每個csv的列標題,基於我試圖構建標記器和插入查詢。

代碼示例

public ItemReader<Gdp> reader1() { 
    FlatFileItemReader<Gdp> reader1 = new FlatFileItemReader<Gdp>(); 
    reader1.setResource(new ClassPathResource("datagdp.csv")); 
    reader1.setLinesToSkip(1); 
    reader1.setLineMapper(new DefaultLineMapper<Gdp>() { 
     { 
      setLineTokenizer(new DelimitedLineTokenizer() { 
       { 
        setNames(new String[] { "region", "gdpExpend", "value" }); 
       } 
      }); 
      setFieldSetMapper(new BeanWrapperFieldSetMapper<Gdp>() { 
       { 
        setTargetType(Gdp.class); 
       } 
      }); 
     } 
    }); 
    return reader1; 
} 
+0

是的,你可以做到這一點。你需要在java中編寫大部分配置,而不是xml – Panther

+0

我在做maven的項目中做了這項工作,但沒有在spring批處理中做出。你可以調整它。 –

+0

@Panther是的,我更喜歡Java配置,因爲我們的項目正在使用 – dazzle

回答

-1

回答你的問題:

  1. 我不知道具體的機制上的春天批量掃描文件。
  2. 你可以使用opencsv作爲通用的CSV閱讀器,有很多機制讀取文件。

關於OpenCSV: 如果您正在使用Maven項目,嘗試導入這種依賴性:

<dependency> 
    <groupId>net.sf.opencsv</groupId> 
    <artifactId>opencsv</artifactId> 
    <version>2.0</version> 
</dependency> 

你可以閱讀您的文件製作的對象爲特定的格式,或像下面這樣的通用標題:

private static List<DadosPeople> extrairDadosPeople() throws IOException { 
    CSVReader readerPeople = new CSVReader(new FileReader(people)); 
    List<PeopleData> listPeople = new ArrayList<PeopleData>(); 
    String[] nextLine; 
    while ((nextLine = readerPeople.readNext()) != null) { 
     PeopleData people = new PeopleData(); 
     people.setIncludeData(nextLine[0]); 
     people.setPartnerCode(Long.valueOf(nextLine[1])); 

     listPeople.add(people); 
    } 
    readerPeople.close(); 
    return listPeople; 
} 

還有很多其他的方式來讀取CSV文件中使用opencsv:

如果您要使用一個Iterator體式格局,你可能會做這樣的事情:

CSVReader reader = new CSVReader(new FileReader("yourfile.csv")); 
String [] nextLine; 
while ((nextLine = reader.readNext()) != null) { 
    // nextLine[] is an array of values from the line 
    System.out.println(nextLine[0] + nextLine[1] + "etc..."); 
} 

或者,如果你可能只是想在一大堆啜成列表,只需調用readAll()...

CSVReader reader = new CSVReader(new FileReader("yourfile.csv")); 
List myEntries = reader.readAll(); 

它會給你一個你可以遍歷的String []列表。如果一切都失敗了,請在這裏查看Javadocs。 如果您想自定義引號字符和分隔符,您會發現可以提供自己的分隔符和引號字符的構造函數。說你是使用標籤爲您的分隔符,你可以做這樣的事情:

CSVReader reader = new CSVReader(new FileReader("yourfile.csv"), '\t'); 

如果你單引號的轉義字符,而不是雙引號它們,您可以用三個參數的構造函數:

CSVReader reader = new CSVReader(new FileReader("yourfile.csv"), '\t', '\''); 

如果您知道內容直到文件後面纔開始,您也可以跳過文件的前幾行。

CSVReader reader = new CSVReader(new FileReader("yourfile.csv"), '\t', '\'', 2); 

我能寫的CSV文件與opencsv:因此,例如,您可以通過執行跳過前兩行呢?

是的。在同一個包中有一個跟CSVReader相同的語義的CSVWriter。例如,寫一個製表符分隔的文件:

CSVWriter writer = new CSVWriter(new FileWriter("yourfile.csv"), '\t'); 
// feed in your array (or convert your data to an array) 
String[] entries = "first#second#third".split("#"); 
writer.writeNext(entries); 
writer.close(); 

如果您更願意使用自己的引號字符,你可以使用構造函數,這需要一個引號字符的三個ARG版本(或隨意傳入CSVWriter.NO_QUOTE_CHARACTER)。

您也可以自定義生成的文件中使用的行結束符(當您從Linux Web應用程序導出到Windows客戶端時,這很方便)。爲此目的有一個構造函數參數。 我可以將SQL錶轉儲爲CSV嗎?

是的,你可以。 CSVWriter上有一個特性,所以你可以傳遞writeAll()一個ResultSet。

java.sql.ResultSet myResultSet = .... 
writer.writeAll(myResultSet, includeHeaders); 

有沒有辦法將我的CSV文件綁定到Javabeans列表?

是的。有一組類允許您根據列名,列位置或自定義映射策略將CSV文件綁定到JavaBeans列表。你可以在com.opencsv.bean包中找到新的類。這裏是你如何映射到根據您的CSV文件中的字段位置上的java bean:

ColumnPositionMappingStrategy strat = new ColumnPositionMappingStrategy(); 
strat.setType(YourOrderBean.class); 
String[] columns = new String[] {"name", "orderNumber", "id"}; // the fields to bind do in your JavaBean 
strat.setColumnMapping(columns); 

CsvToBean csv = new CsvToBean(); 
List list = csv.parse(strat, yourReader); 
+1

這不是Spring Batch。由於Spring Batch已經實現了整個CSV閱讀機制,因此您在這裏重新發明了輪子。 – Thrax

+0

正如我回答,我不知道一個「春天的批量方式」來做到這一點,但opencsv可以讀取和寫入CSV文件以及... –

4

使用MultiResourceItemReader掃描所有文件。
我認爲你需要一種分類的ItemReader作爲MultiResourceItemReader.delegate,但SB不提供這種功能,所以你必須自己寫。
對於ItemProcessorItemWriter SB提供分類器感知實現(ClassifierCompositeItemProcessorClassifierCompositeItemWriter)。
顯然更多不同的輸入文件你有更多的XML配置必須寫入,但它應該很直接。

+0

嗯,讓我一次採取一步。我怎樣才能從csv獲得列標題。我已經把我的示例代碼放在 – dazzle

+2

以上提取標題使用FlatFileItemReader.setSkippedLinesCallback –

+0

很酷,謝謝。現在我該如何將這些價值傳遞給讀者? – dazzle