Diskuze: Java POI - Aktualizace dat
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.


Matúš Olejník:1.8.2018 13:53
Ahoj minimálne v tomto kúsku kódu kde načítavaš dáta z txt súboru, do poľa data, ktoré nikde nepoužiješ
while ((line = br.readLine()) != null) {
String[] data = line.split(";");
System.out.println();
}
namiesto toho chceš vkladať dáta z premennej line do ktorej síce v tom cykle vyššie postupne načítavaš riadky, ale robíš to mimo for cyklu v ktorom chceš zapisovať do nového súboru.
Rovnako veľmi nechápem ako presne to chceš mergnúť mohol by si poslať
obrázok pôvodnej tabuľky, txt súbor ktorým ju chceš aktualizovať a
obrázok excelu ako by to malo na konci vyzerať (sťačí pár riadkov, ktoré
zvládneš aj ručne)
Ahoj, tady ti posílám obrázky jak by to mělo fungovat.
Původní .xlsx soubor:
https://imgur.com/a/Cl4TcmO
Textový soubor pro záměnu dat:
https://imgur.com/a/qslxTyB
A výsledný sobubor .xlsx:
https://imgur.com/a/i73vAcR
Matúš Olejník:1.8.2018 15:08
Na nečisto lebo musím ísť od PC ale zatial skús postupne zavolať metódy ako sú v poradí
public void createWorkBook(File excelFile) {
try {
FileInputStream fis = new FileInputStream(excelFile);
workbook = WorkbookFactory.create(fis);
} catch (IOException | InvalidFormatException | EncryptedDocumentException ex) { //rozbit po jednom
ex.printStackTrace();
}
}
public void loadSheet(int sheetNumber) {
try {
sheet = workbook.getSheetAt(sheetNumber);
}
catch (EncryptedDocumentException ex) {
ex.printStackTrace();
}
}
public void update(){
try(BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
String line = br.readLine();
int rowIndex = 0;
while (line != null) {
String[] cells = line.split(";");
for(int col = 0; col < cells.length; col++){
sheet.getRow(rowIndex).createCell(col).setCellValue(cells[col]);
}
rowIndex++;
line = br.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
plus nejaký save, záloha atď
Ahoj, zkusil jsem si ten kód přepsat a udělat jak jsi říkal. Sice se mi program spustí a napíše ,,BUILD SUCCESSFUL", ale bohužel se mi nevytvoří výsledný soubor. Už jsem z toho opravdu bezradný, mohl by jsi mi s tím, prosím, pomoci ještě víc?
Matúš Olejník:1.8.2018 20:18
Takto mi to funguje, aj keď, keď to píšeš do txt súboru tak by si to
nemohol rovno upravovať v tom exceli?
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
public class TestUpdate {
private Sheet sheet;
private Workbook workbook;
private File excelFile;
public void backupFile(){
File file = excelFile;
File backup = new File("backup"
+ file.getName().substring(file.getName().lastIndexOf(".")));
try {
Files.copy(excelFile.toPath(), backup.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
catch (IOException ex) {
ex.printStackTrace();
}
}
public void createWorkBook(File excelFile) {
try {
this.excelFile = excelFile;
FileInputStream fis = new FileInputStream(excelFile);
workbook = WorkbookFactory.create(fis);
} catch (IOException | InvalidFormatException | EncryptedDocumentException ex) { //rozbit po jednom
ex.printStackTrace();
}
}
public void loadSheet(int sheetNumber) {
try {
sheet = workbook.getSheetAt(sheetNumber);
}
catch (EncryptedDocumentException ex) {
ex.printStackTrace();
}
}
public void update(File txtFile){
try(BufferedReader br = new BufferedReader(new FileReader(txtFile))) {
String line = br.readLine();
int rowIndex = 0;
while (line != null) {
String[] cells = line.split(";");
for(int col = 0; col < cells.length; col++){
sheet.getRow(rowIndex).createCell(col).setCellValue(cells[col]);
}
rowIndex++;
line = br.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void saveFile() {
try {
FileOutputStream fileOut = new FileOutputStream(excelFile);
workbook.write(fileOut);
fileOut.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
import java.io.File;
public class MainClass {
public static void main(String[] args){
TestUpdate t = new TestUpdate();
t.createWorkBook(new File("excelFile.xlsx"));
t.backupFile();
t.loadSheet(0);
t.update(new File("txtFile.txt"));
t.saveFile();
}
}
+20 Zkušeností
+2,50 Kč

No asi by to bylo jednodušší, ale řeším problém, že spousty souborů
mám v .txt a potřebuji je převést do excelu bez toho, abych to musel vše
složitě opisovat. A povedlo se mi je překonvertovat, ale když jsem zjistil,
že mám víc souborů pro jednu tabulku tak jsem začal řešit tenhle problém
a nemohl na něj přijít.
Každopádně mi to teď vyhazuje chybu ,,java.lang.NullPointerException", a
když smažu cyklus ,,while (line != null)" tak to funguje bez problému, ale
zase se mi nevytvoří ten soubor.. Tak já už nevím kde dělám chybu..
Každopádně moc děkuji za pomoc!
Matúš Olejník:1.8.2018 21:40
Taktiež môžeš ten txt súbor uložiť ako CSV a v exceli prejsť do Údaje -> Z textu -> Vybrať ten CSV súbor -> Vyskočí nastavenie tam vyberieš ako oddelovač bodkočiarku a dokončíš nastavenie a máš to v tabuľke.
No a krajšiu chybu ako NullPointerException si ani dostať nemohol Malo by ti tam písať aj
viacero textu k tomu a dokonca aj riadok kde bola, skopíruj to sem. Cestu k
súboru si dal správnu? Prípade sem hoď svoj kód, ale tak ako som to poslal
to funguje.
No to mě popravdě ani nenapadlo, každopádně teď už bych to chtěl
dotáhnout přes tu Javu.
Chybu mi to vypsalo takto:
Exception in thread "main" java.lang.NullPointerException
at testupdate.Update.update(Update.java:64)
at testupdate.TestUpdate.main(TestUpdate.java:12)
/home/radek/.cache/netbeans/8.2/executor-snippets/run.xml:53: Java returned:
1
BUILD FAILED (total time: 0 seconds)
Myslím, že cestu jsem nastavil dobře a kód ti ještě dám sem:
public static void main(String[] args) {
Update t = new Update();
t.createWorkBook(new File("excel.xlsx"));
t.backupFile();
t.loadSheet(0);
t.update(new File("test.txt"));
t.saveFile();
}
public class Update {
private Sheet sheet;
private Workbook workbook;
private File excelFile;
public void backupFile() {
File file = excelFile;
File backup = new File("backup"
+ file.getName().substring(file.getName().lastIndexOf(".")));
try {
Files.copy(excelFile.toPath(), backup.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void createWorkBook(File excelFile) {
try {
this.excelFile = excelFile;
FileInputStream fis = new FileInputStream(excelFile);
workbook = WorkbookFactory.create(fis);
} catch (IOException | InvalidFormatException | EncryptedDocumentException ex) { //rozbit po jednom
ex.printStackTrace();
}
}
public void loadSheet(int sheetNumber) {
try {
sheet = workbook.getSheetAt(sheetNumber);
} catch (EncryptedDocumentException ex) {
ex.printStackTrace();
}
}
public void update(File txtFile) {
try (BufferedReader br = new BufferedReader(new FileReader(txtFile))) {
String line = br.readLine();
int rowIndex = 0;
while (line != null) {
String[] cells = line.split(";");
for (int col = 0; col < cells.length; col++) {
sheet.getRow(rowIndex).createCell(col).setCellValue(cells[col]);
}
rowIndex++;
line = br.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void saveFile() {
try {
FileOutputStream fileOut = new FileOutputStream(excelFile);
workbook.write(fileOut);
fileOut.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Matúš Olejník:1.8.2018 23:08
Skús upraviť ten while takto
while (line != null) {
String[] cells = line.split(";");
if(sheet.getRow(rowIndex) == null) {
sheet.createRow(rowIndex);
}
for(int col = 0; col < cells.length; col++){
sheet.getRow(rowIndex).createCell(col).setCellValue(cells[col]);
}
rowIndex++;
line = br.readLine();
}
Skvěle! Už vše funguje jak má, strašně moc ti děkuji za ochotu a tvůj
čas. Můžu mít ještě
poslední dotaz před uzavřením tohoto vlákna?
Narazil jsem na problém. Potřeboval bych tam přidat podmínku, že pokud se
liší záhlaví sloupců u těchto dvou soborů tak se aktualizace dat
neprovede. Zkusil jsem tedy načíst první řádek souboru .xlsx a poté první
řádek souboru .txt a pak dát podmínku, ale bohužel z nějakého důvodu mi
to nedovoluje to porovnat.
public void update(File txtFile) {
try (BufferedReader br = new BufferedReader(new FileReader(txtFile))) {
String line = br.readLine();
int rowIndex = 0;
Sheet prvniRadek = workbook.getSheetAt(0);
String text = br.readLine();
if(prvniRadek == text) {
while (line != null) {
String[] cells = line.split(";");
if (sheet.getRow(rowIndex) == null) {
sheet.createRow(rowIndex);
}
for(int col = 0; col < cells.length; col++){
sheet.getRow(rowIndex).createCell(col).setCellValue(cells[col]);
}
rowIndex++;
line = br.readLine();
} }
} catch (IOException e) {
e.printStackTrace();
}
}
Petr Štechmüller:2.8.2018 19:25
Ahoj, nefunguje Ti to, protože to špatně porovnáváš. Přečti si tady rozdíl mezi
== a equals.
A hlavně porovnáváš dvě neporovnatelné věci.
if(prvniRadek == text)
Na jedné straně máš instanci typu Sheet a na druhé straně instanci typu String. Je tedy potřeba nejdříve srovnat typy instancí a pak je porovnat pomocí equals.
Matúš Olejník:2.8.2018 20:55
Rád som pomohol Ohľadom
tej druhej otázky, tak vysvetlenie ti napísal Petr. Tu som napísal nejakú
funkciu ako by si mohol porovnať zadaný riadok s dátami, hádam, že je veľa
vecí ktoré by to mohli pokaziť, ale s tým už sa môžeš hrať ty
public boolean rowEqualsData(Row row, String[] data){
if(row.getLastCellNum() != data.length){
return false;
}
for(int i = 0; i < data.length; i++){
Cell cell = row.getCell(i);
if(cell.getCellTypeEnum().equals(CellType.NUMERIC)){
if(!String.valueOf(cell.getNumericCellValue()).equals(data[i])){
return false;
}
} else if (cell.getCellTypeEnum().equals(CellType.STRING)){
if(!cell.getStringCellValue().equals(data[i])){
return false;
}
} else {
throw new UnsupportedOperationException(
"Comparing cell with cell type "
+ cell.getCellTypeEnum().toString()
+ " is not implemented yet"
);
}
}
return true;
}
Zobrazeno 13 zpráv z 13.