напишите заголовок, чтобы имя сегмента по умолчанию также печаталось на основе максимального вхождения

Прямо сейчас я могу написать заголовок, но не могу напечатать имя заголовка, которое находится внутри сегмента. Есть ли способ сделать это?

входной файл-

1john dew BA xxx  
1sam hart MA yyy

Он не печатает имя по умолчанию внутри сегмента.
выходной файл-

Record,FirstName,LastName,Title,Filler  
1,john,dew,22,85,22,85,22,85,BA,xxx  
1,sam,hart,78,45,78,45,78,45,MA,yyy

Ява:

public class XlsWriter {
    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"));

        out.write("headers",null);
        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.Employee">
            <field name="record" length="3" literal="AAA" rid="true" />
            <field name="firstName" length="5" />
            <field name="lastName" length="5" />
            <segment name="error" collection="list" minOccurs="0"
                maxOccurs="3" class="com.Error">
                <field name="origin_of_error" length="2" />
                <field name="fld_name" length="2" />

            </segment>
            <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" />
            <segment name="error" collection="list" minOccurs="0"
                maxOccurs="5" class="com.Error">
                <field name="origin_of_error" default="origin_of_error" />
                <field name="fld_name" default="fld_name" />

            </segment>
            <field name="titleColumn" default="Title" />
            <field name="fillerColumn" default="Filler" />
        </record>
        <record name="a" minOccurs="0" maxOccurs="unbounded"
            class="com.Employee">
            <field name="record" length="3" literal="AAA" rid="true" />
            <field name="firstName" length="5" />
            <field name="lastName" length="5" />
            <segment name="error" collection="list" minOccurs="0"
                maxOccurs="3" class="com.Error">
                <field name="origin_of_error" length="2" />
                <field name="fld_name" length="2" />

            </segment>
            <field name="title" length="5" />
            <field name="filler" length="5" />
        </record>
    </stream>
</beanio>

Ожидаемый результат-

Запись,Имя,Фамилия,origin_of_error,fld_name,origin_of_error,fld_name,origin_of_error,fld_name,Title,Filler
1,john,dew,22,85,22,85,22,85,BA,xxx
1, Сэм, Харт, 78, 45, 78, 45, 78, 45, Массачусетс, гггг


person Vishal    schedule 30.07.2019    source источник
comment
Будет ли сегмент всегда повторяться 3 раза при печати заголовков столбцов в файле CSV или это зависит от размера (количества записей) списка ошибок?   -  person nicoschl    schedule 30.07.2019
comment
если сегмент имеет максимальное вхождение 3 раза, то он будет печатать запись 3 раза   -  person Vishal    schedule 30.07.2019


Ответы (1)


Чтобы заголовки столбцов были динамическими, нам нужно переместить заголовки столбцов в свои собственные классы.

Добавьте классы HeaderColumns и ErrorColumns, чтобы они содержали имена разных столбцов.

public class HeaderColumns {

  private String recordColumn = "Record";
  private String firstNameColumn = "FirstName";
  private String lastNameColumn = "LastName";
  private String titleColumn = "Title";
  private String fillerColumn = "Filler";
  private List<ErrorColumns> errorColumns;

  public void addErrorColumns(final ErrorColumns errorColumn) {
    if (errorColumns == null) {
      errorColumns = new ArrayList<>();
    }
    errorColumns.add(errorColumn);
  }
  // getter/setters removed
}

Обратите внимание на метод addErrorColumns.

public class ErrorColumns {

  private String originOfErrorColumn = "origin_of_error";
  private String fldNameColumn = "fld_name";
  // getter/setters removed
}

Нам нужно добавить метод в класс Employee, чтобы возвращать количество прочитанных ошибок.

public class Employee {

  private String record;
  private String firstName;
  private String lastName;
  private String title;
  private String filler;
  private int errorCount;
  private List<Error> error;

  public int getErrorCount() {
    return error != null ? error.size() : 0;
  }
  // getter/setters removed
}

Определение записи столбца headers в файле сопоставления теперь очень похоже на фактическое определение записи для данных a.

<stream name="EmployeeInfoCSV" format="csv">
  <record name="headers" minOccurs="1" maxOccurs="1" 
          class="com.HeaderColumns">
    <field name="recordColumn" rid="true" literal="Record"/>
    <field name="firstNameColumn"/>
    <field name="lastNameColumn"/>
    <segment name="errorColumns" collection="list" minOccurs="0" maxOccurs="unbounded" 
             class="com.ErrorColumns">
      <field name="originOfErrorColumn"/>
      <field name="fldNameColumn"/>
    </segment>
    <field name="titleColumn"/>
    <field name="fillerColumn"/>
  </record>
  <record name="a" minOccurs="0" maxOccurs="unbounded" 
          class="com.Employee">
    <field name="record" length="1"/>
    <field name="firstName" maxLength="5"/>
    <field name="lastName" maxLength="5"/>
    <segment name="error" collection="list" minOccurs="0" maxOccurs="unbounded" 
             class="com.Error">
      <field name="origin_of_error" maxLength="2"/>
      <field name="fld_name" maxLength="2"/>
    </segment>
    <field name="title" maxLength="5"/>
    <field name="filler" maxLength="5"/>
  </record>
</stream>

Теперь нам нужно убедиться, что список errorColumns заполнится тем же количеством объектов, которое мы прочитали для первой записи Employee.

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"));

    boolean columnHeadersWritten = false;
    Object record;
    while ((record=br.read())!=null) {

      if (!columnHeadersWritten) {
        final Employee employee = (Employee) record;
        final HeaderColumns headerColumns = new HeaderColumns();
        for (int i = 0; i < employee.getErrorCount(); i++) {
          headerColumns.addErrorColumns(new ErrorColumns());
        }
        out.write(headerColumns);
        columnHeadersWritten = true;
      }

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

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

Теперь у нас есть динамические заголовки столбцов, основанные на фактическом количестве ошибок, считанных из первой записи Employee.

person nicoschl    schedule 30.07.2019
comment
я могу это сделать, но если максимальное количество раз произойдет в 100 раз больше, чем я сделаю, это только проблема - person Vishal; 31.07.2019
comment
Обновил мой ответ и заставил его работать более динамично - person nicoschl; 31.07.2019