Search code examples
javabean-io

want to write header in csv from beanIO field name tag


I want to write a header in csv file as my text file does not contain any header so i want to write it from beanIO field name tag

I am having a beanIO with two stream one for reading and another for writing

this is input file.... textInput.txt-
1john dew BA xxx
1sam hart MA yyy

public static void main(String[] args) throws Exception {

    StreamFactory factory = StreamFactory.newInstance();

    factory.load("C:\\Users\\PV5057094\\Demo_workspace\\XlsxMapper\\src\\main\\resources\\Employee.xml");


BeanReader br = factory.createReader("EmployeeInfo",new File("C:\\Temp\\Soc\\textInput.txt"));

    BeanWriter out = factory.createWriter("EmployeeInfoCSV", new File("C:\\Temp\\Soc\\output.csv"));



    Object record;

    while ((record=br.read())!=null) {


        out.write(record);

        System.out.println("Record Written:" + record.toString());

    }

    // in.close();
    out.flush();
    out.close();
   }

}


BeanIO-

<?xml version="1.0" encoding="UTF-8"?>
<beanio xmlns="http://www.beanio.org/2012/03"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.beanio.org/2012/03 http://www.beanio.org/2012/03/mapping.xsd">

    <stream name="EmployeeInfo" format="fixedlength">

        <record name="a" minOccurs="0" maxOccurs="unbounded"
            class="com.aexp.gmnt.imc.record.submission.Employee">
            <field name="record" length="1" literal="1" rid="true"/>
            <field name="firstName" length="5"/>
            <field name="lastName" length="5"/>
            <field name="title" length="5"/>
            <field name="filler" length="5"/>
        </record>

    </stream>


    <stream name="EmployeeInfoCSV" format="csv">
        <record name="a" minOccurs="0" maxOccurs="unbounded"
            class="com.aexp.gmnt.imc.record.submission.Employee">
            <field name="record" length="1" literal="1" rid="true"/>
            <field name="firstName" length="5"/>
            <field name="lastName" length="5"/>
            <field name="title" length="5"/>
            <field name="filler" length="5"/>
        </record>
    </stream>
</beanio>

Expected output-

Record,FirstName,LastName,Title,Filler
1,john,dew,BA,xxx
1,sam,hart,MA,yyy


Solution

  • You have to define a new record in your EmployeeInfoCSV stream definition that will contain the column names as the default value for the field, e.g.

    <record name="headers" minOccurs="1" maxOccurs="1">
      <field name="recordColumn" default="Record"/>
    

    Then you have to tell your BeanWriter to first write out a record of "headers" before outputting the rest of the file.

    out.write("headers", null);
    

    You must also change the length attribute on the a record in your CSV stream to be maxLength, otherwise you'll get padding on the output and it would still look like a fixed length format.

    Change

    <field name="firstName" length="5"/>
    

    to

    <field name="firstName" maxLength="5"/>
    

    Putting this all together then:

    public static void main(String[] args) throws Exception {
    
      StreamFactory factory = StreamFactory.newInstance();
      factory.load("C:\\Users\\PV5057094\\Demo_workspace\\XlsxMapper\\src\\main\\resources\\Employee.xml");
    
      BeanReader br = factory.createReader("EmployeeInfo",new File("C:\\Temp\\Soc\\textInput.txt"));
      BeanWriter out = factory.createWriter("EmployeeInfoCSV", new File("C:\\Temp\\Soc\\output.csv"));
    
      // write the column headers to the output file
      out.write("headers", null);
    
      Object record;
      while ((record=br.read())!=null) {
        out.write(record);
        System.out.println("Record Written:" + record.toString());
      }
    
      br.close();  // yes, also close the reader
      out.flush();
      out.close();
    }
    

    And the mapping file:

    <?xml version="1.0" encoding="UTF-8"?>
    <beanio xmlns="http://www.beanio.org/2012/03"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.beanio.org/2012/03 http://www.beanio.org/2012/03/mapping.xsd">
    
      <stream name="EmployeeInfo" format="fixedlength">
          <record name="a" minOccurs="0" maxOccurs="unbounded"
              class="com.aexp.gmnt.imc.record.submission.Employee">
              <field name="record" length="1" literal="1" rid="true"/>
              <field name="firstName" length="5"/>
              <field name="lastName" length="5"/>
              <field name="title" length="5"/>
              <field name="filler" length="5"/>
          </record>
      </stream>
    
      <stream name="EmployeeInfoCSV" format="csv">
        <record name="headers" minOccurs="1" maxOccurs="1">
          <field name="recordColumn" default="Record"/>
          <field name="firstNameColumn" default="FirstName"/>
          <field name="lastNameColumn" default="LastName"/>
          <field name="titleColumn" default="Title"/>
          <field name="fillerColumn" default="Filler"/>
        </record>
        <record name="a" minOccurs="0" maxOccurs="unbounded" 
                class="com.aexp.gmnt.imc.record.submission.Employee">
          <field name="record" length="1"/>
          <field name="firstName" maxLength="5"/>
          <field name="lastName" maxLength="5"/>
          <field name="title" maxLength="5"/>
          <field name="filler" maxLength="5"/>
        </record>
      </stream>
    </beanio>