Aus Excel auslesen und in DB speichern

heimedall

Grünschnabel
Hallo Java-Gemeinde,

ich stehe vor einem Problem und könnte die Hilfe von Java-Fachmännern gebrauchen.

Ich lese mittels der JExcel-API eine Exceldatei aus und speichere den Inhalt in einer MySQL-Datenbank. Das funktioniert auch alles ganz gut, nur stellt sich mir jetzt ein Problem in den Weg:

Der Inhalt der Exceldatei verändert sich von Zeit zu Zeit, sprich es kommen neue Zeilen hinzu. Die Exceldatei lese ich in bestimmten Zeitabständen ein. Nun will ich aber nur die neu hinzugekommenen Zeilen in die Datenbank speichern. Das Problem hierbei ist, dass ich nicht die Möglichkeit habe beim Speichern in die Datenbank einzelne Felder als unique zu definieren, weil der Inhalt der Felder sich ändern kann. Das heißt, ich habe kein eindeutiges Feld das ich als Vergleichswert zwischen der Exceldatei und der Datenbank verwenden kann.

Nun suche ich nach einer Möglichkeit wie ich das bewerkstelligen kann. Ich wäre für jeden Tipp und jede Anregung sehr dankbar.

Gruß
heimedall
 

youza

Erfahrenes Mitglied
Kommen nur neue Zeilen hinzu oder werden auch vorhandene Zeilen verändert? du könntest einen Hashcode aus den erhaltenen Daten erstellen und diesen in der Datenbank abspeichern hat sich die Zeile nicht geändert so muss du den Datensatz nicht in die Datenbank schreiben.

Noch ein kleines Beispiel wie ich das mit dem Hash meine:
PoiReadExcelFile
Java:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class PoiReadExcelFile {
	public static void main(String[] args) {
		try {
			FileInputStream fileInputStream = new FileInputStream("poi-test.xls");
			HSSFWorkbook workbook = new HSSFWorkbook(fileInputStream);
			HSSFSheet worksheet = workbook.getSheet("POI Worksheet");
			String strRow = "";
			System.out.println(worksheet.getLastRowNum());
			int []ids = new int[worksheet.getLastRowNum()+1];
			for (int i = 0; i <	worksheet.getLastRowNum()+1; i++) {
				for (int j = 0; j < worksheet.getRow(i).getLastCellNum(); j++) {
					strRow += worksheet.getRow(i).getCell(j);
				}
				ids[i] = strRow.hashCode();
				strRow = "";
			}
			/*
			 * Die ids kannst du als eindeutig hernehmen da dies HashCodes sind es sei denn es darf exakt die Gleiche Zeile 
			 * 2 mal vorkommen
			 */
			
			
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Falls du Tatsächlich kein Feld in der Datenbank hinzufügen darfst fällt mir nur ein eine .txt Datei mit den ganzen Hashes bei jedem speichern zu erstellen und dise dann abzugleichen.

Ungefähr so: (klappt allerdings noch nicht ganz so wie ich des gerner hätte)
Java:
package writer;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class PoiReadExcelFile {
	public static void main(String[] args) {
		try {
			FileInputStream fileInputStream = new FileInputStream(
					"poi-test.xls");
			HSSFWorkbook workbook = new HSSFWorkbook(fileInputStream);
			HSSFSheet worksheet = workbook.getSheet("POI Worksheet");
			String strRow = "";

			Reader fileReader = new FileReader(new File("log.txt"));
			BufferedReader breader = new BufferedReader(fileReader);
			ArrayList<Integer> oldIds = new ArrayList<Integer>();
			String line = "INIT";
			while (line != null && !line.isEmpty()) {
				line = breader.readLine();
				if (line == null)
					break;
				line.trim();
				oldIds.add(Integer.parseInt(line));

			}
			breader.close();

			ArrayList<HSSFRow> arlRows = new ArrayList<HSSFRow>();
			int id;
			boolean isNew = true;
			for (int i = 0; i < worksheet.getLastRowNum() + 1; i++) {
				for (int j = 0; j < worksheet.getRow(i).getLastCellNum(); j++) {
					strRow += worksheet.getRow(i).getCell(j);
				}
				id = strRow.hashCode();
				for (int j = 0; j < oldIds.size(); j++) {
					if (oldIds.get(j) == id) {
						isNew = false;
						break;
					}
				}
				if (isNew)
					arlRows.add(worksheet.getRow(i));
				strRow = "";
			}
			for (int i = 0; i < arlRows.size(); i++) {
				insertToDatabase(arlRows.get(i));
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static boolean insertToDatabase(HSSFRow newRow) {

		// Datenbank operationen ausführen
		addIdToFile(newRow);
		String strRow = "";
		for (int j = 0; j < newRow.getLastCellNum(); j++) {
			strRow += newRow.getCell(j);
		}
		System.out.println(strRow);
		return true;
	}

	private static boolean addIdToFile(HSSFRow newRow) {

		try {
			FileWriter fileWritter = new FileWriter(new File("log.txt"));
	        BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
			String strRow = "";
			for (int j = 0; j < newRow.getLastCellNum(); j++) {
				strRow += newRow.getCell(j);
			}
			bufferWritter.write(String.valueOf(strRow.hashCode()));
	        bufferWritter.close();
	        fileWritter.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
		return true;
	}
}

Viele Grüße
Youza
 

Thinker

Mitglied
Der Inhalt der Exceldatei verändert sich von Zeit zu Zeit, sprich es kommen neue Zeilen hinzu. Die Exceldatei lese ich in bestimmten Zeitabständen ein. Nun will ich aber nur die neu hinzugekommenen Zeilen in die Datenbank speichern. Das Problem hierbei ist, dass ich nicht die Möglichkeit habe beim Speichern in die Datenbank einzelne Felder als unique zu definieren, weil der Inhalt der Felder sich ändern kann. Das heißt, ich habe kein eindeutiges Feld das ich als Vergleichswert zwischen der Exceldatei und der Datenbank verwenden kann.

Wenn nur neue Zeilen hinzukommen, dann kannst du die Zeilennummer als eindeutiges "Pseudo-Feld" verwenden.

Wenn auch Zeilen wegfallen können, dann kannst du in einer Transaktion ein Truncate auf die Tabelle machen und dann alle Datensätze neu einfügen. Wenn keine doppelten Einträge drin vorkommen kannst du auch alle Felder als einen Schlüssel prüfen.