Naučit se PHP Naučit se PHP
Extra 10 % bodů navíc a tričko zdarma při zadání kódu "TRIKO10"
Avatar
Elix Novel
Člen
Avatar
Elix Novel:1.8.2018 13:23

Zdravím, pracuji na programu, který bude umět aktualizovat data v souboru xlsx. Program by měl načíst soubor .txt, ve kterém budou nové buňky - oddělené středníkem a poté je zapsat do již existujícího souboru .xlsx.
Už nad tím bádám strašně dlouho a nemůžu na to přijít.

Zkusil jsem: Program by měl načíst workbook ze starého .xlsx souboru. Poté zjistit počet buněk v souboru a zavolat funkci pro aktualizaci dat. Funkce načte textový soubor a vše co je v textovém souboru na stejném místě jako ve starém xlsx souboru tak přepíše novými daty. Aby program poznal jak oddělovat buňky používám oddělovač středník. Všechny data ukládá do dočasného souboru, který poté přepíše na aktualizovaný soubor ,,vystup.xlsx"

public class TestUpdate {

    public static void main(String[] args) throws IOException, InvalidFormatException {
        XSSFWorkbook workbook = new XSSFWorkbook(new File("excel.xlsx"));

        for (int s = 0; s < workbook.getNumberOfSheets(); s++) {
            XSSFSheet sheet = (XSSFSheet) workbook.getSheetAt(s);
            update(sheet);
        }
    }

    public static void update(XSSFSheet sheet) throws FileNotFoundException, IOException {
        String unl = "textovySoubor.txt";
        File file = new File(unl);
        FileReader fileReader = new FileReader(file);
        BufferedReader br = new BufferedReader(fileReader);
        File temp = new File("temp.txt");
        String line = null;
        OutputStreamWriter osw = null;
        OutputStream os = null;
        BufferedWriter bw = null;
        os = (OutputStream) new FileOutputStream(temp);
        osw = new OutputStreamWriter(os);
        bw = new BufferedWriter(osw);

        while ((line = br.readLine()) != null) {
            String[] data = line.split(";");
            System.out.println();

        }
        for (int i = 0; i < sheet.getPhysicalNumberOfRows(); i++) {
            Row row = (Row) sheet.getRow(i);
            if (sheet.getPhysicalNumberOfRows() > 0) {
                bw.write(row.toString());
                bw.write(',');
                for (int j = 0; j < sheet.getPhysicalNumberOfRows(); j++) {
                    if (row.toString().contains(",")) {
                        bw.write(line);
                        bw.write(row.toString());
                        bw.write(line);

                    } else {
                        bw.write(row.toString());
                    }

                    bw.write(line);
                }
            }
            bw.newLine();

        }
        bw.flush();
        bw.close();
        File rename = new File("vystup.xlsx");
        temp.renameTo(rename);
    }
}

Chci docílit: Zkoušel jsem použít staré knihovny JExcel, ale tam není podpora nového formátu .xlsx (Excel 2007 a novější). Za každou pomoc budu strašně rád.

 
Odpovědět 1.8.2018 13:23
Avatar
Odpovídá na Elix Novel
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) ;)

Editováno 1.8.2018 13:53
Nahoru Odpovědět 1.8.2018 13:53
/* I am not sure why this works but it fixes the problem */
Avatar
Elix Novel
Člen
Avatar
Elix Novel:1.8.2018 14:22

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

Editováno 1.8.2018 14:22
 
Nahoru Odpovědět 1.8.2018 14:22
Avatar
Odpovídá na Elix Novel
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ď

Nahoru Odpovědět 1.8.2018 15:08
/* I am not sure why this works but it fixes the problem */
Avatar
Elix Novel
Člen
Avatar
Elix Novel:1.8.2018 19:06

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?

 
Nahoru Odpovědět 1.8.2018 19:06
Avatar
Odpovídá na Elix Novel
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? :D

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();
    }
}
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět 1.8.2018 20:18
/* I am not sure why this works but it fixes the problem */
Avatar
Elix Novel
Člen
Avatar
Elix Novel:1.8.2018 21:16

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.Nu­llPointerExcep­tion", 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!

 
Nahoru Odpovědět 1.8.2018 21:16
Avatar
Odpovídá na Elix Novel
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 NullPointerEx­ception si ani dostať nemohol :D 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.

Editováno 1.8.2018 21:42
Nahoru Odpovědět 1.8.2018 21:40
/* I am not sure why this works but it fixes the problem */
Avatar
Elix Novel
Člen
Avatar
Elix Novel:1.8.2018 21:52

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.NullPo­interException
at testupdate.Up­date.update(Up­date.java:64)
at testupdate.Tes­tUpdate.main(Tes­tUpdate.java:12)
/home/radek/.cache/net­beans/8.2/exe­cutor-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();
        }
    }
}
 
Nahoru Odpovědět 1.8.2018 21:52
Avatar
Odpovídá na Elix Novel
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();
}
Nahoru Odpovědět 1.8.2018 23:08
/* I am not sure why this works but it fixes the problem */
Avatar
Elix Novel
Člen
Avatar
Elix Novel:2.8.2018 19:20

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();
    }
}
Editováno 2.8.2018 19:22
 
Nahoru Odpovědět 2.8.2018 19:20
Avatar
Petr Štechmüller
Překladatel
Avatar
Odpovídá na Elix Novel
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.

Nahoru Odpovědět 2.8.2018 19:25
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Odpovídá na Elix Novel
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;
}
Nahoru Odpovědět  +1 2.8.2018 20:55
/* I am not sure why this works but it fixes the problem */
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 13 zpráv z 13.