了解しました。以下は、比較元ディレクトリパスと比較先ディレクトリパスを選択し、それぞれをbefore
テーブルとafter
テーブルに取り込み、差分を抽出してSJISエンコーディングで差分.csv
として出力するJava Swingアプリケーションのコードです。
コード例
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.CSVWriter;
import com.opencsv.exceptions.CsvValidationException;
public class CsvToSQLiteApp extends JFrame {
private static final String DB_URL = "jdbc:sqlite:example.db";
private JTextField beforeDirPathField;
private JTextField afterDirPathField;
private JTextField outputCsvPathField;
private JLabel statusLabel;
public CsvToSQLiteApp() {
setTitle("CSV to SQLite App");
setSize(700, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(5, 5, 5, 5);
JLabel beforeDirPathLabel = new JLabel("比較元ディレクトリパス:");
beforeDirPathField = new JTextField(20);
JButton selectBeforeDirButton = new JButton("Select Before Directory");
JLabel afterDirPathLabel = new JLabel("比較先ディレクトリパス:");
afterDirPathField = new JTextField(20);
JButton selectAfterDirButton = new JButton("Select After Directory");
JLabel outputCsvPathLabel = new JLabel("Output CSV Path:");
outputCsvPathField = new JTextField(20);
JButton diffButton = new JButton("Export Difference to CSV");
statusLabel = new JLabel();
statusLabel.setForeground(Color.BLUE);
gbc.gridx = 0;
gbc.gridy = 0;
add(beforeDirPathLabel, gbc);
gbc.gridx = 1;
add(beforeDirPathField, gbc);
gbc.gridx = 2;
add(selectBeforeDirButton, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
add(afterDirPathLabel, gbc);
gbc.gridx = 1;
add(afterDirPathField, gbc);
gbc.gridx = 2;
add(selectAfterDirButton, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
add(outputCsvPathLabel, gbc);
gbc.gridx = 1;
add(outputCsvPathField, gbc);
gbc.gridx = 2;
add(diffButton, gbc);
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 3;
add(statusLabel, gbc);
selectBeforeDirButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result = fileChooser.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedDir = fileChooser.getSelectedFile();
beforeDirPathField.setText(selectedDir.getAbsolutePath());
}
}
});
selectAfterDirButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result = fileChooser.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedDir = fileChooser.getSelectedFile();
afterDirPathField.setText(selectedDir.getAbsolutePath());
}
}
});
diffButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String beforeDirPath = beforeDirPathField.getText();
String afterDirPath = afterDirPathField.getText();
String outputCsvPath = outputCsvPathField.getText();
try (Connection conn = DriverManager.getConnection(DB_URL)) {
importCsvToTable(conn, beforeDirPath, "before");
importCsvToTable(conn, afterDirPath, "after");
exportDiffToCsv(conn, "before", "after", outputCsvPath);
statusLabel.setText("Difference exported to " + outputCsvPath);
} catch (SQLException ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(null, "Error processing CSV files: " + ex.getMessage());
}
}
});
}
private void importCsvToTable(Connection conn, String csvDirPath, String tableName) {
File folder = new File(csvDirPath);
File[] listOfFiles = folder.listFiles((dir, name) -> name.endsWith(".csv"));
if (listOfFiles == null) {
JOptionPane.showMessageDialog(null, "No CSV files found in the directory: " + csvDirPath);
return;
}
for (File file : listOfFiles) {
try (CSVReader csvReader = new CSVReaderBuilder(new InputStreamReader(new FileReader(file), "SJIS"))
.withSkipLines(0)
.build()) {
String[] headers = csvReader.readNext();
if (headers == null) {
continue;
}
while (headers[0].startsWith("#")) {
headers = csvReader.readNext();
if (headers == null) {
break;
}
}
createTable(conn, tableName, headers);
String[] row;
while ((row = csvReader.readNext()) != null) {
if (row[0].startsWith("#")) {
continue;
}
insertRow(conn, tableName, headers, row);
}
} catch (IOException | CsvValidationException | SQLException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "Error processing file " + file.getName() + ": " + e.getMessage());
}
}
}
private void createTable(Connection conn, String tableName, String[] headers) throws SQLException {
try (Statement stmt = conn.createStatement()) {
String columns = String.join(" TEXT, ", headers) + " TEXT";
String createTableSQL = String.format("CREATE TABLE IF NOT EXISTS %s (%s)", tableName, columns);
stmt.execute(createTableSQL);
}
}
private void insertRow(Connection conn, String tableName, String[] headers, String[] row) throws SQLException {
String columns = String.join(", ", headers);
String placeholders = String.join(", ", Arrays.asList(row).stream().map(col -> "?").toArray(String[]::new));
String insertSQL = String.format("INSERT INTO %s (%s) VALUES (%s)", tableName, columns, placeholders);
try (java.sql.PreparedStatement pstmt = conn.prepareStatement(insertSQL)) {
for (int i = 0; i < row.length; i++) {
pstmt.setString(i + 1, row[i]);
}
pstmt.executeUpdate();
}
}
private void exportDiffToCsv(Connection conn, String tableA, String tableB, String outputCsvPath) {
String sql = String.format("SELECT * FROM %s EXCEPT SELECT * FROM %s", tableA, tableB);
try (CSVWriter writer = new CSVWriter(new OutputStreamWriter(new FileWriter(outputCsvPath), "SJIS"));
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
writer.writeAll(rs, true);
} catch (SQLException | IOException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "Error exporting difference: " + e.getMessage());
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new CsvToSQLiteApp().setVisible(true);
}
});
}
}
説明
-
レイアウトの設定:
-
GridBagLayout
を使用してコンポーネントを柔軟に配置。 - 各種ラベル(
JLabel
)、テキストフィールド(JTextField
)、ボタン(JButton
)をレイアウトに追加。
-
-
ディレクトリ選択機能:
-
JFileChooser
を使ってディレクトリ選択ダイアログを表示し、ユーザーが選択したディレクトリをテキストフィールドに設定。
-
-
CSVのインポート:
-
importCsvToTable
メソッドで、指定されたディレクトリ内のCSVファイルを読み込み、SQLiteのテーブルにインポート。 - CSVファイルをSJISエンコーディングで読み込み、最初の行をカラム名として使用し、コメント行を無視。
-
-
テーブルの作成とデータの挿入:
-
createTable
メソッドで動的にカラムを取得しテーブルを作成。 -
insertRow
メソッドでデータを挿入。
-
-
差分のエクスポート:
-
exportDiffToCsv
メソッドで2つのテーブル間の差分を抽出し、結果を指定されたCSVファイルにSJISエンコーディングで書き出す。
-
このアプリケーションを実行することで、GUIを通じてディレクトリを選択し、CSVファイルの取り込みや差分抽出が簡単に行えるようになります。
以下は、必要な依存関係を含むMavenプロジェクトのpom.xml
ファイルの例です。このプロジェクトは、SQLite JDBCドライバとOpenCSVライブラリを使用します。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>csv-to-sqlite-app</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- SQLite JDBC Driver -->
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.34.0</version>
</dependency>
<!-- OpenCSV Library -->
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.5.2</version>
</dependency>
<!-- JUnit for testing (optional) -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
説明
-
<dependencies>
セクション:- SQLite JDBCドライバ(
org.xerial:sqlite-jdbc:3.34.0
) - OpenCSVライブラリ(
com.opencsv:opencsv:5.5.2
) - (オプション)JUnit 4.13.2(テストのため)
- SQLite JDBCドライバ(
-
<build>
セクション:-
maven-compiler-plugin
を使用してJavaコンパイラのバージョンを指定しています。この例ではJava 17を使用しています。
-
このpom.xml
ファイルを使用することで、プロジェクトに必要な依存関係が自動的にダウンロードおよび設定されます。これにより、CSVファイルをSQLiteデータベースに取り込み、差分を抽出してCSVファイルに出力するJava Swingアプリケーションを構築できます。