티스토리 뷰

TableView CSV Export

  • JavaFX TableView를 사용하면서 Table Data를 CSV 형태로 Export 하는 기능이 필요할 때가 있습니다.
  • TableView 전시 자체가 Grid 형태이기 때문에 형태 그대로 CSV로 Export 하는 경우가 종종 있습니다.
    • 아래 이미지 처럼 

  • 이때 json2flat 라이브러리를 사용하여 간단하게 구현하는 방법에 대해서 알아보고자 합니다.

JFlat

  • JSON 문서를 CSV 형태로 변환해주는 라이브러리 입니다.
    • 내부적으로 google-gson JsonPath를 사용했다고 함
  • 아래 위치에서 테스트를 해볼 수 있다고 합니다.
 

opendevl/Json2Flat

Converting JSON documents to flat CSV. Contribute to opendevl/Json2Flat development by creating an account on GitHub.

github.com


라이브러리 적용

  • 빌드 방식에 맞추어 적용해주도록 합시다.
 

Maven Repository: com.github.opendevl » json2flat » 1.0.3

Converting JSON documents to flat CSV com.github.opendevl json2flat 1.0.3 // https://mvnrepository.com/artifact/com.github.opendevl/json2flat compile group: 'com.github.opendevl', name: 'json2flat', version: '1.0.3' // https://mvnrepository.com/artifact/co

mvnrepository.com

gradle

// https://mvnrepository.com/artifact/com.github.opendevl/json2flat
compile group: 'com.github.opendevl', name: 'json2flat', version: '1.0.3'

maven

<!-- https://mvnrepository.com/artifact/com.github.opendevl/json2flat -->
<dependency>
    <groupId>com.github.opendevl</groupId>
    <artifactId>json2flat</artifactId>
    <version>1.0.3</version>
</dependency>

TableView에 Export 버튼 추가

  • 저번 TableView 구현 포스트에서 사용한 UI를 재활용 하겠습니다. 혹시 못보신 분들은 참고바랍니다.
 

(JavaFX) JavaFX TableView 사용법 ver.2

들어가며 이전에 썼던 글인 JavaFX TableView 사용법 이 시간이 지나서 보니 조금 설명이 허접한 것 같기도 하고.. 리뉴얼이 필요할 것 같았다. [JavaFX] Table View 사용법 Table View 사용법 이번 시간에는 Java..

jinseongsoft.tistory.com


ExportableTable.fxml

  • tableViewContainer는 위 TableView예제에서 구현한 TableViewController가 들어갈 AnchorPane이라고 생각하면 됩니다.
  • TableView 하단에 Export 버튼을 만들어 Export 기능을 집어넣도록 할 예정입니다.
<fx:root style="-fx-background-color: #A2A5AC;" type="AnchorPane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" stylesheets="@../../../fx.css" prefWidth="800">
  <VBox  focusTraversable="false"  AnchorPane.bottomAnchor="60.0" AnchorPane.leftAnchor="20.0" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="20.0">
    <AnchorPane fx:id="tableViewContainer"/>
    <Button fx:id="exportButton" text="Export" prefWidth="100" prefHeight="30"/>
  </VBox>
</fx:root>

 

ExportableTableController.java

  • 주입 받은 tableData List는 이미 구현된 TableController에 넣어줍니다. (TableController는 인스턴스를 새로 생성)
  • export button 클릭시에 handleExportCsv 메소드를 실행하여 Export 기능을 수행합니다.

handleExportCsv()

  • FileChooser를 통해서 CSV 파일을 저장 경로를 사용자로부터 입력 받도록 합니다.
  • ExtensionFilter는 FileChooser 전시시에 저장 파일의 확장자 prefix라고 보면 됩니다. 

  • 파일 지정 후에는 tableController의 data를 array 형태로 가져와 JSON으로 변환합니다. 
    • JsonUtil 은 GSON을 간편하게 사용할 용도로 생성된 정적 Util 클래스로 아래서 자세히 설명 예정
  • 이후 JFlat 라이브러리를 사용하여 json을 CSV로 변환하여 파일에 저장하는 형태이다.
public class ExportableTableController extends AnchorPane {
  TableController tableController;
  @FXML
  private AnchorPane tableViewContainer;
  @FXML
  private Button exportButton;

  public ExportableTableController(List<TableData> tableDataList) {
    FxUtil.initializeFont();
    FxUtil.loadFxml(this);
    init(tableDataList);
  }

  private void init(List<TableData> tableDataList) {
    tableController = new TableController(tableDataList);
    tableViewContainer.getChildren().add(tableController);
    exportButton.setOnAction(event -> {
      handleExportCsv();
    });
  }

  private void handleExportCsv() {
    final FileChooser.ExtensionFilter csvFilter = new FileChooser.ExtensionFilter("CSV Files (*.csv)", "*.csv");
    final FileChooser.ExtensionFilter allFilter = new FileChooser.ExtensionFilter("All Files (*.*)", "*.*");

    FileChooser fileChooser = new FileChooser();
    fileChooser.setTitle("Save CSV");
    fileChooser.getExtensionFilters().addAll(csvFilter, allFilter);
    //CSV FileChooser 초기 이름 설정
    fileChooser.setInitialFileName("SAMPLE-CSV.csv");

    File file = fileChooser.showSaveDialog(this.getScene().getWindow());
    try {
      if (file != null) {

        String json = JsonUtil.getGsonSingleton().toJson(this.tableController.getTableView().getItems().toArray()).replaceAll("\"id\".*?,", "");
        JFlat flatMe = new JFlat(json);
        flatMe.json2Sheet().headerSeparator().write2csv(file.getPath());
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

JsonUtil.java

  • GSON 라이브러리를 간편하게 쓰기 위한 유틸 클래스
  • 아래 ZonedDateTimeTypeAdapter는 ZonedDateTime 인스턴스를 Json으로 변환시에 발생하는 오류를 해결하기 위한 Serializer로 자세한 내용은 아래 포스트 참고
 

(Java) Gson 사용시 ZonedDateTime JSON Serialize/Deserialize 방법

들어가며 Gson을 사용하여 ZonedDateTime 객체를 Serialize/Deserialize 하는 경우가 있다. public void test() { String json = new GsonBuilder().create().toJson(ZonedDateTime.now()); ZonedDateTime dateTim..

jinseongsoft.tistory.com

public class JsonUtil {
    private static Gson gson;

    private JsonUtil() {
    }

    /**
     * JSON 을 사용하기 위해서 Gson이 필요한 경우 활용. (기본적으로는 JEST 라이브러리에게 전달하기 위한 용도)
     *
     * @return Gson 인스턴스
     */
    public static synchronized Gson getGsonSingleton() {
        if (gson == null) {
            gson = getGsonBuilder()
                    .excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.STATIC)
                    .create();
        }
        return gson;
    }

    /**
     * 객체를 Json으로 변환해 주는 메소드.
     *
     * @param object 변환하기 위한 객체
     * @return String Json String
     */
    public static <T> String toJson(T object) {
        return getGsonSingleton().toJson(object);
    }

    /**
     * 객체를 보기좋은 Json String 으로 변환해 주는 메소드.
     *
     * @param object 변환하기 위한 객체
     * @return String Json String
     */
    public static <T> String toPrettyJson(T object) {
        return getGsonBuilder().setPrettyPrinting().create().toJson(object).replace("\n", "\r\n");
    }


    /**
     * Json String을 객체로 변환해 주는 메소드.
     *
     * @param json Json String
     * @param classOfT 객체 타입
     * @param <T> 객체 타입
     * @return 객체 타입
     */
    public static <T> T toInstance(String json, Class<T> classOfT) {
        return getGsonSingleton().fromJson(json, classOfT);
    }

    public static <T> T toInstance(String json, Type type) {
        return getGsonSingleton().fromJson(json, type);
    }

    private static GsonBuilder getGsonBuilder() {
        final GsonBuilder builder = new GsonBuilder();
        builder.registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeTypeAdaptor());

        return builder;
    }
}

테스트

  • 테스트 코드를 작성하여 실행 해봅시다.
public class ExportableTableTest extends Application {

  @Test
  public void test() {
    launch();
  }

  private List<TableData> generateTableData() {
    List<TableData> tableDataList = new ArrayList<>();
    tableDataList.add(new TableData("1",  ZonedDateTime.now().minusSeconds(1), "I'm 1", true));
    tableDataList.add(new TableData("2",  ZonedDateTime.now().minusSeconds(2), "I'm 2", false));
    tableDataList.add(new TableData("3",  ZonedDateTime.now().minusSeconds(3), "I'm 3", true));
    tableDataList.add(new TableData("4",  ZonedDateTime.now().minusSeconds(4), "I'm 4", false));
    tableDataList.add(new TableData("5",  ZonedDateTime.now().minusSeconds(5), "I'm 5", true));
    tableDataList.add(new TableData("6",  ZonedDateTime.now().minusSeconds(6), "I'm 6", true));
    tableDataList.add(new TableData("7",  ZonedDateTime.now().minusSeconds(7), "I'm 7", false));
    tableDataList.add(new TableData("8",  ZonedDateTime.now().minusSeconds(8), "I'm 8", false));
    tableDataList.add(new TableData("9",  ZonedDateTime.now().minusSeconds(9), "I'm 9", true));
    return tableDataList;
  }

  @Override
  public void start(Stage primaryStage) throws Exception {
    ExportableTableController controller = new ExportableTableController(generateTableData());
    primaryStage.setScene(new Scene(controller));
    primaryStage.setTitle("Table Test");
    primaryStage.show();
  }
}

 

  • 실행 후 Export 버튼을 누르면 아래와 같이 전시되고 파일명을 선택하고 저장을 합니다.

 

  • 이후에 파일을 열어보면 TableView Data가 전시되는 것을 확인할 수 있습니다.


관련글

 

(JavaFX) JavaFX TableView 사용법 ver.2

들어가며 이전에 썼던 글인 JavaFX TableView 사용법 이 시간이 지나서 보니 조금 설명이 허접한 것 같기도 하고.. 리뉴얼이 필요할 것 같았다. [JavaFX] Table View 사용법 Table View 사용법 이번 시간에는 Java..

jinseongsoft.tistory.com

 

[JavaFX] 실시간 업데이트 되는 Timer(시계) 컨트롤 구현 방법

들어가며 JavaFX를 이용해 실시간으로 업데이트되는 Timer 컨트롤을 구현해보고자 합니다. 원본 소스는 아래 위치에 있습니다. rlawlstjd0077/JavaFxPlayGround Contribute to rlawlstjd0077/JavaFxPlayGround dev..

jinseongsoft.tistory.com

 

[JavaFx] Tray Icon에 메뉴 추가 방법 (Tray Menu 사용법)

들어가며 JavaFX의 Tray Icon에 메뉴를 추가하는 방법에 대해서 알아보도록 하겠습니다. Tray Menu Tray Icon에 추가하는 메뉴는 아래와 같은 형태로 Tray Icon에 오른쪽 마우스 클릭을 했을 때 전시되는 메뉴를..

jinseongsoft.tistory.com

 

[JavaFX] Window Close(X 버튼 클릭) 시에 Application 종료 방법 (프로세스 종료)

들어가며 JavaFX Application 개발 시 Window를 Close했을 때 (X 버튼 클릭시) 내부 프로세스는 종료되지 않습니다. 이럴 때 프로세스까지 종료하는 방법을 알아보도록 하겠습니다. 해결 방법 먼저 Window Close..

jinseongsoft.tistory.com


끝으로

이 글이 도움이 되었다면, 하단의 Google 광고 👎👎👎 한번씩 클릭 부탁 드립니다. 🙏🙏🙏

광고 클릭은 많은 힘이 됩니다! 

 

반응형
댓글