Create text files with spring batch

To create a file over spring batch, first you need a marshaller with a Reader and a Writer.

The Reader:

<bean id="fileReader">
  <property name="dataSource" ref="dataSource" />
  <property name="sql" value="SELECT * FROM table" />
  <property name="rowMapper">
    <bean class="de.package.rowmapper.FileRowMapper" />
  </property>
</bean>

The RowMapper which is used by the Reader:

package de.package.rowmapper;
 
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.RowMapper;
import de.package.domainObjects.SftpFileObject;
 
public class FileRowMapper implements RowMapper {
 
  public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
    FileLineObject fileLine = new FileLineObject();
    try {
      fileLine.setDbField1(rs.getString("dbField1"));
      fileLine.setDbField2(rs.getString("dbField2"));
      fileLine.setDbField3(rs.getString("dbField3"));
      fileLine.setDbField4(rs.getString("dbField4"));
      fileLine.setDbField5(rs.getString("dbField5"));
    } catch (SQLException e) {
      System.out.println("Can't create data row for export File.");
    }
    return fileLine;
  }
}

The Domain Object which is used by the Reader:

package de.package.domainObjects;
 
public class fileLineObject implements java.io.Serializable {
 
  private static final long serialVersionUID = 1L;
 
  public String dbField1;
  public String dbField2;
  public String dbField3;
  public String dbField4;
  public String dbField5;
 
  public String getDbField1() {
    return dbField1;
  }
 
  public void setDbField1(String dbField1) {
    this.dbField1= dbField1;
  }
 
  public String getDbField2() {
    return dbField2;
  }
 
  public void setDbField2(String dbField2) {
    this.dbField2= dbField2;
  }
 
  public String getDbField3() {
    return dbField3;
  }
 
  public void setDbField3(String dbField3) {
    this.dbField3= dbField3;
  }
 
  public String getDbField4() {
    return dbField4;
  }
 
  public void setDbField4(String dbField4) {
    this.dbField4= dbField4;
  }
 
  public String getDbField5() {
    return dbField5;
  }
 
  public void setDbField5(String dbField5) {
    this.dbField5= dbField5;
  }
}

The Writer:

<bean id="fileWriter" scope="step">
  <property name="resource" value="file:path/to/file/filename.csv" />
  <property name="encoding" value="ISO-8859-1" />
  <property name="headerCallback">
    <bean class="de.package.helper.HeaderCallback" />
  </property>
  <property name="lineAggregator">
    <bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
      <property name="delimiter" value=";" />
      <property name="fieldExtractor">
        <bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
          <property name="names" value="dbField1, dbField2, dbField3, dbField4, dbField5" />
        </bean>
      </property>
    </bean>
  </property>
</bean>

The HeaderCallback we only need, if we want to create a headline in the file, which is not coming from the reader. If we want to use the headline, we have to use the following small java class, which fills the line and write it to the file.
There is also the possibility to use a FooterCallback to write line(s) at the end of the file after the RowMapper has done his work, but in my example I do not used it.

package de.package.helper;
 
import java.io.IOException;
import java.io.Writer;
import org.springframework.batch.item.file.FlatFileHeaderCallback;
 
public class HeaderCallback implements FlatFileHeaderCallback {
 
  @Override
  public void writeHeader(Writer writer) throws IOException {
    writer.write("FieldHeadline1;FieldHeadline2;FieldHeadline3;FieldHeadline4;FieldHeadline5");
  }
}

These beans together can be now called by a BatchJob.

 

Print Friendly, PDF & Email

Leave a Comment

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*
*