package ru.egspt; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.time.LocalTime; import java.util.ArrayList; import javax.swing.table.AbstractTableModel; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class ReportTableModel extends AbstractTableModel{ private Object[] header; private Object[][] data; //создаем модель без данных public ReportTableModel(){} public ReportTableModel(Object[] header, Object[][] data){ setHeader(header); setData(data); } //создаем модель по данным Data public ReportTableModel(Data data){ setHeader(getHeaderByQuize(data)); setData(data); } //создаем модель по данным предварительно переданным в App public ReportTableModel(App app){ setHeader(getHeaderByQuize(app.getData())); setData(app.getData()); } @Override public int getRowCount() { return getData().length; } @Override public int getColumnCount() { return getHeader().length; } @Override public Object getValueAt(int rowIndex, int columnIndex) { return getData()[rowIndex][columnIndex]; } /** * @param header the header to set */ public void setHeader(Object[] header) { this.header = header; } /** * Настройка заголовков отчета * @param data */ public Object[] getHeaderByQuize(Data report){ /** * Определение количества заголовков: * первые три заголовка определяются таблицей пользователей и всегда постоянны * остальные заголовки определяются: * количеством тестов, в прохождении которых участвовали пользователи, помноженным на * количество отчетных данных (результат сдачи теста и время потраченное на прохождение теста) */ ArrayList header = new ArrayList(); header.add("id"); header.add("login"); header.add("mail"); //заголовки по названиям опросов int i = 0; while (i < report.getQuizes().size()){ header.add(report.getQuizes().get(i).getName()); header.add(""); i++; } //преобразуем список в массив Object[] h = new Object[header.size()]; int j = 0; while (j < header.size()){ h[j] = header.get(j); j++; } return h; } /** * @return the header */ public Object[] getHeader() { return header; } /** * */ public void setData(Object[][] data){ this.data = data; } /** * добавить проверку соответствия данных поля и заголовка столбца */ public void setData(Data report) { //создаем объект data - инициализация переменной Object[][] d = new Object[report.getUsers().size()][3 + 2*report.getQuizes().size()]; //формируем строку заголовков Object[] header = new Object[3 + 2*report.getQuizes().size()]; int i = 0; header[i] = "id"; i++; header[i] = "login"; i++; header[i] = "mail"; i++; int j = 0; while (j < report.getQuizes().size()){ header[i] = report.getQuizes().get(j).getName(); i++; header[i] = "time"; i++; j++; } //заголовки в консоль int h = 0; while (h < header.length){ System.out.println("header " + h + ": " + header[h]); h++; } //построчно заполняем модель отчета данными int userCurr = 0;//номер строки в отчете while (userCurr < report.getUsers().size()){ int col = 0;//номер столбца в строке //заполняем данные пользователя (имя и почту) d[userCurr][col] = report.getUsers().get(userCurr).getId(); col++; d[userCurr][col] = report.getUsers().get(userCurr).getLogin(); col++; d[userCurr][col] = report.getUsers().get(userCurr).getMail(); col++; //Заполняем результаты тестирвоания пользователя //Перебираем результаты, получаем результаты текущего пользователя int resultCurr = 0; while (resultCurr < report.getResults().size()){ if (report.getResults().get(resultCurr).getUserid() == report.getUsers().get(userCurr).getId()){ //если текущий результат относится к текущему пользователю //взять индекс теста из результата и сопоставить с полями заголовков (определить номер ячейки для формирования записи) String quizname = ""; int quizCurr = 0; while (quizCurr < report.getQuizes().size()){ if (report.getResults().get(resultCurr).getQuizid() == report.getQuizes().get(quizCurr).getId()){ quizname = report.getQuizes().get(quizCurr).getName(); } quizCurr++; } //поиск индекса ячейки, куда писать результаты int ihead = 0; int headerCurr = 0;//номер ячейки в которую писать результаты тестирования (+2) while (ihead < header.length){ if (quizname.equals(header[ihead])){ headerCurr = ihead; ihead++; } ihead++; } //формируем ячейку grade d[userCurr][headerCurr] = report.getResults().get(resultCurr).getGrade(); //формируем ячейку time Long time = report.getResults().get(resultCurr).getTime(); String t = LocalTime.MIN.plusSeconds(time).toString(); d[userCurr][headerCurr + 1] = t; } resultCurr++; } userCurr++; } setData(d); } /** * @return the data */ public Object[][] getData() { return data; } public void toExcell(File file){ System.out.println("Формирование report.xlsx ..."); // создание самого excel файла в памяти XSSFWorkbook book = new XSSFWorkbook(); // создание листа XSSFSheet sheet = book.createSheet("Report"); //пишем названия тестов в заголовки xlsx int row = 0;//строка int col = 0;//столбец Row r = sheet.createRow(row); while (col < getHeader().length){ r.createCell(col).setCellValue(getHeader()[col].toString()); col++; } System.out.println("Заголовки в report.xlsx сформированы."); //построчно пишем данные System.out.println("Построчно пишем данные .... "); row++; int userCurr = 0; while (userCurr < getData().length){ col = 0; r = sheet.createRow(row); while(col < getHeader().length){ Cell c = r.createCell(col); if (getData()[userCurr][col] == null){ c.setCellValue(""); } else{ c.setCellValue(getData()[userCurr][col].toString()); } // col++; } userCurr++; row++; } //пишем книгу в файл //String location = System.getProperty("user.dir") + "\\report.xlsx"; //Path path = Paths.get(location); if (file.exists()) { try (FileOutputStream out = new FileOutputStream(file)) { book.write(out); book.close(); out.close(); System.out.println("Excel файл успешно перезаписан!"); System.out.println(file); } catch (IOException e){ e.printStackTrace(); } } else { try (FileOutputStream out = new FileOutputStream(file)) { book.write(out); book.close(); out.close(); System.out.println("Excel файл успешно создан!"); System.out.println(file); } catch (IOException e){ e.printStackTrace(); } } } /* * выводим данные модели в консоль */ public void toConsole(){ //заголовки int i = 0; while (i < getHeader().length){ System.out.print(getHeader()[i] + " "); i++; } System.out.println(); //данные i = 0; while (i < getData().length){ int j = 0; while (j < getData()[i].length){ System.out.print(getData()[i][j] + " "); j++; } System.out.println(); i++; } System.out.println(getHeader().toString()); } /* * обновление данных отчета по данным заявки, доабвляем в отчет столбцы: * - organization/наименование организации * - object/объект строительства * - name/Фамилия Имя Отчество * - position/должность * - result/имеются или нет результаты * * данные из файла подтягиваются по полю Login, * столбцы должны быть размещены в строгой последовательности: * 1. login * 2. ... * 3. * * Лист с которого берем данные должен быть первым (желательно единственным) */ public void updateReport(File file) throws IOException{ // создание самого excel файла в памяти XSSFWorkbook book = new XSSFWorkbook(new FileInputStream(file)); XSSFSheet sheet = book.getSheetAt(0); int height = sheet.getLastRowNum();//количество строк в таблице Row row = sheet.getRow(0); int wide = row.getLastCellNum();//количество столбцов в таблице (первые 5 столбцов должны жестко соответствовать шаблону) //перебираем строки файла int i = 0; while (i < height){ if ((String)getData()[i][1] == row.getCell(0).getStringCellValue()){ //переписываем данные строки в модель } i++; } book.close(); } }