Разбор XML и вывод в Excel

428
08 августа 2017, 14:29

Есть XML файл с таким содержимым. Строк ROW много. Как в JAVAFX разобрать такой файл и экспортировать в Excel чтобы дочерние узлы ROW были колонками. С чего вообще нужно начать? Что почитать? Есть какой-то туториал?

<?xml version="1.0" encoding="UTF-8"?>
<TABLE>
   <ROW>
      <SRV_CODE>00001</SRV_CODE>
      <SRV_TEXT>Услуга 1</SRV_TEXT>
      <QTY_OBSL_1>0</QTY_OBSL_1>
      <QTY_ISS_4>0</QTY_ISS_4>
      <QTY_ISS_6>0</QTY_ISS_6>
      <QTY_OBSL_7>0</QTY_OBSL_7>
      <QTY_ISS_9>0</QTY_ISS_9>
   </ROW>
   <ROW>
      <SRV_CODE>00002</SRV_CODE>
      <SRV_TEXT>Услуга 2</SRV_TEXT>
      <QTY_OBSL_1>0</QTY_OBSL_1>
      <QTY_ISS_4>3</QTY_ISS_4>
      <QTY_ISS_6>0</QTY_ISS_6>
      <QTY_OBSL_7>0</QTY_OBSL_7>
      <QTY_ISS_9>0</QTY_ISS_9>
   </ROW>
   <ROW>
      <SRV_CODE>00003</SRV_CODE>
      <SRV_TEXT>Услуга 3</SRV_TEXT>
      <QTY_OBSL_1>0</QTY_OBSL_1>
      <QTY_ISS_4>0</QTY_ISS_4>
      <QTY_ISS_6>0</QTY_ISS_6>
      <QTY_OBSL_7>0</QTY_OBSL_7>
      <QTY_ISS_9>0</QTY_ISS_9>
   </ROW>
</TABLE>
Answer 1

Начать надо с того, что JavaFX - это платформа для разработки GUI и только. Так что в JavaFX никак. Для разбора XML нужна соответствующая библиотека. Вариантов много, тонкостей не меньше. Есть целые книги посвящённые вопросу. Если в общих чертах, нужен либо SAX-парсер, либо DOM-парсер. Я часто слышал мнение, что с первым работать сложнее, но я, например, так не считаю. Зато SAX использует намного меньше памяти и позволяет разбирать xml-файлы огромного размера. А для работы с офисными документами в Java самая популярная библиотека - это Apache POI. Подытоживая, с помощью классов из org.xml.sax читаете xml-файл, а с помощью классов из org.apache.poi пишите в xls-файл.

import java.io.IOException;
import java.io.File;
import java.io.FileOutputStream;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class SAXHandler extends DefaultHandler {
    private final XSSFWorkbook workbook;
    private final XSSFSheet sheet;
    private XSSFRow row;
    private int rowNum = 0;
    private int colNum = 0;
    private String tagName;
    private StringBuilder tagContent;
    public SAXHandler() {
        workbook = new XSSFWorkbook();
        sheet = workbook.createSheet("Импорт из XML");
    }
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        tagName = qName;
        if(tagName.equals("ROW")) {
            row = sheet.createRow(rowNum++);
            tagContent = new StringBuilder();
            colNum = 0;
        }
    }
    @Override        
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if(!(tagName.equals("TABLE") || tagName.equals("ROW"))) {
            Cell cell = row.createCell(colNum++);
            cell.setCellValue(tagContent.toString());
            tagContent = new StringBuilder();        
        }
    }
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if(!(tagName.equals("TABLE") || tagName.equals("ROW")))
            tagContent.append(new String(ch, start, length).trim());
    }
    public void save() {
        try(FileOutputStream out = new FileOutputStream(new File("test.xlsx"))) {
            workbook.write(out);
        }
        catch (IOException exc) {
            exc.printStackTrace();
        }
    }
    public static void main(final String args[]) {
        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();
            SAXHandler handler = new SAXHandler();
            saxParser.parse("test.xml", handler);
            handler.save();
        }
        catch(SAXException ex) {}
        catch(ParserConfigurationException ex) {}
        catch(IOException ex) {}
    }
}

Естественно, в реальной программе функцию разбора XML и функцию сохранения XLS лучше разнести в разные классы и контролировать соответствие между именем обрабатываемого тега и номером колонки.

READ ALSO
Настройка SQL запросов в Hibernate

Настройка SQL запросов в Hibernate

Добрый день, разрабатываю систему отчетности в виде web-приложенияИспользую Spring и Hibernate

331
Redirect:/ После авторизации Spring java

Redirect:/ После авторизации Spring java

На сайте система авторизацииSpring security

291
Микросервисная архитектура Java

Микросервисная архитектура Java

Посредством чего или с помощью чего взаимодействует один микросервис с другим?

444
Библиотеки для работы с COM-портом

Библиотеки для работы с COM-портом

Нужно сделать примитивное общение с устройством через COM-портКакие есть вообще библиотеки для этого? Что ни нахожу в гугле - то пизанские...

343