Как лучше считать файл из Excel Selenium Java

Привет. Нашел рабочий код и запустил - вроде работает - считывает. Но как-то мне этот метод не нравится, особенно распечатка данных. Есть какой-то способ полегче считать файл?
Вот смотрите какой код у меня

package test;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;


import java.io.File;
import java.io.FileInputStream;
import java.net.MalformedURLException;

public class GetTestDataFromExcel {
    static WebDriver driver;
    private String baseUrl;
    private StringBuffer verificationErrors = new StringBuffer();
    public static String fileToBeRead = "С:\\test.xls";

    @BeforeClass
    public static void SetUp() throws MalformedURLException {
        System.setProperty("webdriver.chrome.driver","C:\\Users\\username\\downloads\\chromedriver_win32\\chromedriver.exe");

        driver = new ChromeDriver();
    }

    @Test
    public void getDataFromExcel() {
        try {
            // Specify the path of file
            File src=new File("C:\\test.xlsx");

            // load file
            FileInputStream fis=new FileInputStream(src);

            // Load workbook
            XSSFWorkbook wb=new XSSFWorkbook(fis);

            // Load sheet- Here we are loading first sheetonly
            XSSFSheet sh1= wb.getSheetAt(0);

            // getRow() specify which row we want to read.

            // and getCell() specify which column to read.
            // getStringCellValue() specify that we are reading String data.


            System.out.println(sh1.getRow(0).getCell(0).getStringCellValue());

            System.out.println(sh1.getRow(0).getCell(1).getStringCellValue());

            System.out.println(sh1.getRow(1).getCell(0).getStringCellValue());

            System.out.println(sh1.getRow(1).getCell(1).getStringCellValue());

            System.out.println(sh1.getRow(2).getCell(0).getStringCellValue());

            System.out.println(sh1.getRow(2).getCell(1).getStringCellValue());

        } catch (Exception e) {

            System.out.println(e.getMessage());

        }
    }
}

Вы получили значение ячейки в 4 строчки кода, разве это плохо?
Причём тут Селениум вообще?

  1. Зачем в топике упоминаете Selenium? Сама задача по всей видимости относится только к библиотеке по работе с .xlsx файлом.
  2. Чем конкретно вам не нравится метод “получить Workbook -> получить Sheet -> получить строку от Sheet,
    -> получить ячейки на строке -> получить содержимое -> напечатать”? Чего вы добиваетесь?

я просто изучаю селениум вебдрайвер. То есть это просто задача по Java?

System.out.println(sh1.getRow(0).getCell(0).getStringCellValue());

            System.out.println(sh1.getRow(0).getCell(1).getStringCellValue());

            System.out.println(sh1.getRow(1).getCell(0).getStringCellValue());

            System.out.println(sh1.getRow(1).getCell(1).getStringCellValue());

            System.out.println(sh1.getRow(2).getCell(0).getStringCellValue());

            System.out.println(sh1.getRow(2).getCell(1).getStringCellValue());

Смущает вот этот код, чтобы получить данные с ячеек, надо писать так. Как сделать в цикле например?

1 А как поправить тему? Я просто изучаю селениум вебдрайвер и наткнулся на считывание файла, но сейчас да понимаю, что это скорее задача просто по Джаве.
2 У меня сейчас заполнены ячейки A1 B1 C1. Я хочу их распечатать
Допустим этот код

            System.out.println(sh1.getRow(0).getCell(0).getStringCellValue());

            System.out.println(sh1.getRow(0).getCell(1).getStringCellValue());

Это показывает, что я печатаю ряд 0 ячейка 0 = то есть A1?

В цикле удалось сделать, вот мой код, только как вместо 3 поставить длину ячеек - рядов пока не знаю

            for (int i=0; i<3; i++) {
                for(int j=0; j<3; j++) {
                    String cellValue = sh1.getRow(i).getCell(j).getStringCellValue();
                    System.out.println(cellValue);
                }
            }

Изучайте API: Index of /apidocs/dev/org/apache/poi/xssf/usermodel

Вроде бы для получения первой и последней строк должны подойти getFirstRowNum() и getLastRowNum() из XSSFSheet, а для получения первой и последней ячеек в строке - getLastCellNum() и getFirstCellNum() из класса Row.

Тогда циклом можно пройтись как-нибудь так:

            for (int i = sh1.getFirstRowNum(); i < sh1.getLastRowNum(); i++) {
                Row row = sh1.getRow(i);
                for(int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {
                    String cellValue = row.getCell(j).getStringCellValue();
                    System.out.println(cellValue);
                }
            }

а что такое переменная ROW?
У меня ее нет в коде
Вот все что есть

            File src=new File("C:\\test.xlsx");

            FileInputStream fis=new FileInputStream(src);

            XSSFWorkbook wb=new XSSFWorkbook(fis);

            XSSFSheet sh1= wb.getSheetAt(0);

Это не переменная, это класс. Вот документация на него: Row (POI API Documentation)

Посмотрите еще раз мой пример. Я там во второй строке создаю и инициализирую объект этого класса: Row row = sh1.getRow(i);

Да, теперь понял.
Сейчас у меня данные только первого ряда, но я так понял цикл же проходит по всем рядам и ячейкам, разве нет?
Ну то есть у меня только первый ряд распечатался, второй нет

Попробуйте поменять условие продолжения цикла на “i <= sh1.getLastRowNum()”

1 лайк

Да, помогло спасибо.
Теперь мне выдает такой список
Alex123
alex@mail.com
asd123asd
Sasha331
sasha@mail.com
qweqwe
Как мне получить доступ к каждому элементу, чтобы я уже мог использовать как тестовые данные в элементе? Ну, например

WebElement el = driver.findElement(By.xpath("xpath"));
el.sendKeys(Alex123);
WebElement el2 = driver.findElement(By.xpath("xpath"));
el2.sendKeys(alex@mail.com);

Мне надо как-то cellValue перекинуть в массив и из массива получить доступ к элементу от индекса уже?

Да, как вариант. Тут уже это зависит от того что это за данные и как предполагается их использовать. Изучите Collections API из JDK, это джавашная нативная абстракция над структурами данных.

1 лайк

Почитаю про коллекции, я так понял это аналог массива - списков?
В общем попробовал сейчас через массив сделать - в резульате что и было до этого, то и распечатывает, только в строку. Короч не получилось иными словами. Что не так у меня в коде?

                    String phrases [] = cellValue.split("\\n");
                    for(int k=0;k<phrases.length;k++){
                        System.out.print(phrases[k] + " ");

                    }

Использвовать JSON
или тхт файл
если не нужен оверхед или хочется прокачаться по ексель манипуляциям

1 лайк

Я ж не понимаю что должно было произойти)
Если что:

  • print() - печатает свой аргумент в стандартный вывод;
  • println() - то же самое, но еще делает перенос на следующую строку;
  • printf() - печатает с форматированием, первый аргумент - шаблон, следующие - подставляются в шаблон.
1 лайк

Примерчик бы под мой пример :slight_smile:

  • код там и там практически одинаковый

@Alex_Alex1 Специально для таких случаев есть библиотека “xls-test”:

Вкупе с селенидом вашу проверку можно вообще в пару строк написать:

File file = $("a#report").download();
XLS spreadsheet = new XLS(file);
assertThat(spreadsheet, containsText("Statement"));