티스토리 뷰
TableView CSV Export
- JavaFX TableView를 사용하면서 Table Data를 CSV 형태로 Export 하는 기능이 필요할 때가 있습니다.
- TableView 전시 자체가 Grid 형태이기 때문에 형태 그대로 CSV로 Export 하는 경우가 종종 있습니다.
- 아래 이미지 처럼
- 이때 json2flat 라이브러리를 사용하여 간단하게 구현하는 방법에 대해서 알아보고자 합니다.
JFlat
- JSON 문서를 CSV 형태로 변환해주는 라이브러리 입니다.
- 내부적으로 google-gson JsonPath를 사용했다고 함
- 아래 위치에서 테스트를 해볼 수 있다고 합니다.
라이브러리 적용
- 빌드 방식에 맞추어 적용해주도록 합시다.
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를 재활용 하겠습니다. 혹시 못보신 분들은 참고바랍니다.
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로 자세한 내용은 아래 포스트 참고
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가 전시되는 것을 확인할 수 있습니다.
관련글
끝으로
이 글이 도움이 되었다면, 하단의 Google 광고 👎👎👎 한번씩 클릭 부탁 드립니다. 🙏🙏🙏
광고 클릭은 많은 힘이 됩니다!
반응형
'프로그래밍 > JavaFX' 카테고리의 다른 글
(JavaFX) FXML에서 ImageView위에 Image 로드 하는 방법 (0) | 2020.05.08 |
---|---|
(JavaFX) JavaFX ImageView 사용법 (이미지 전시 방법) (0) | 2020.05.08 |
[JavaFX] JavaFX Window Close(X 버튼 클릭) 시에 종료 여부 Alert 전시 방법 (0) | 2020.04.29 |
[JavaFX] Window Close(X 버튼 클릭) 시에 Application 종료 방법 (프로세스 종료) (0) | 2020.04.29 |
[JavaFX] Chart 사용시 메모리 누수 문제 해결방법 (0) | 2020.04.29 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- JavaFX Window Close
- java
- 이펙티브 자바
- 자전거
- 자바
- 배낭 여행
- windows
- Java UI
- 자전거 여행
- JavaFX 테이블뷰
- 일본여행
- springboot
- 이펙티브
- 일본 자전거 여행
- 스프링부트
- 텐트
- TableView
- JavaFX 종료
- git
- JavaFX Table View
- 일본 여행
- JavaFX
- effective java
- intelij
- 배낭여행
- 인텔리제이
- 일본 배낭여행
- 이펙티브자바
- 방통대 과제물
- effectivejava
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함